home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / samba / patches / samba-1.007 / samba-1
Encoding:
Text File  |  1996-06-04  |  394.5 KB  |  13,960 lines

  1. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/docs/Support.txt samba-1.9.16alpha5/docs/Support.txt
  2. --- samba-1.9.16alpha4/docs/Support.txt    Sun May  5 17:15:53 1996
  3. +++ samba-1.9.16alpha5/docs/Support.txt    Sun Jun  2 00:19:00 1996
  4. @@ -41,8 +41,8 @@
  5.  ------------------------------------------------------------------------------
  6.  READING - ENGLAND
  7.  
  8. -Philip Hands                | E-Mail: info@hands.com  Tel:+44 1734 545656
  9. -Philip Hands Computing Ltd. | Mobile: +44 802 242989  Fax:+44 1734 474655
  10. +Philip Hands                | E-Mail: info@hands.com  Tel:+44 118 9545656
  11. +Philip Hands Computing Ltd. | Mobile: +44 802 242989  Fax:+44 118 9474655
  12.  Unit 1, Cherry Close, Caversham, Reading  RG4 8UP  ENGLAND
  13.  
  14.  Samba experience: 
  15. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/docs/smb.conf.5 samba-1.9.16alpha5/docs/smb.conf.5
  16. --- samba-1.9.16alpha4/docs/smb.conf.5    Sat Jun  1 01:13:35 1996
  17. +++ samba-1.9.16alpha5/docs/smb.conf.5    Wed Jun  5 01:16:21 1996
  18. @@ -1962,14 +1962,6 @@
  19.  
  20.  .B Example:
  21.      protocol = LANMAN1
  22. -.SS proxy name resolution (G)
  23. -
  24. -This is a boolean that controls if nmbd will respond to broadcast name
  25. -queries on behalf of other hosts. You may need to set this to no for
  26. -some older clients.
  27. -
  28. -.B Default:
  29. -    proxy name resolution = yes
  30.  .SS public (S)
  31.  A synonym for this parameter is 'guest ok'.
  32.  
  33. @@ -2548,6 +2540,33 @@
  34.  .B Example:
  35.       wide links = no
  36.  
  37. +.SS wins proxy (G)
  38. +
  39. +This is a boolean that controls if nmbd will respond to broadcast name
  40. +queries on behalf of other hosts. You may need to set this to no for
  41. +some older clients.
  42. +
  43. +.B Default:
  44. +    wins proxy = no
  45. +.SS wins support (G)
  46. +
  47. +This boolean controls if Samba will act as a WINS server. You should
  48. +normally set this to true unless you already have another WINS server
  49. +on the network.
  50. +
  51. +.B Default:
  52. +    wins support = yes
  53. +.SS wins server (G)
  54. +
  55. +This specifies the DNS name of the WINS server that Samba should
  56. +register with. If you have a WINS server on your network then you
  57. +should set this to the WINS servers name.
  58. +
  59. +This option only takes effect if Samba is not acting as a WINS server
  60. +itself. 
  61. +
  62. +.B Default:
  63. +    wins server = 
  64.  .SS workgroup (G)
  65.  
  66.  This controls what workgroup your server will appear to be in when
  67. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/Makefile samba-1.9.16alpha5/source/Makefile
  68. --- samba-1.9.16alpha4/source/Makefile    Sat Jun  1 01:15:11 1996
  69. +++ samba-1.9.16alpha5/source/Makefile    Wed Jun  5 01:16:25 1996
  70. @@ -503,9 +503,10 @@
  71.  UTILOBJ = $(UTILOBJ1) md4.o loadparm.o params.o pcap.o username.o time.o
  72.  PARAMOBJ = $(UTILOBJ) ufc.o smbpass.o access.o 
  73.  SMBDOBJ1 = $(PARAMOBJ) trans2.o message.o dir.o printing.o locking.o
  74. -SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o quotas.o
  75. +SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o quotas.o uid.o
  76.  SMBDOBJ = $(SMBDOBJ1) $(SMBDOBJ2) $(VTP_OBJ)
  77. -
  78. +NMBDOBJ1 = $(UTILOBJ) nmblib.o nameresp.o nmbsync.o nameannounce.o namedb.o nameelect.o
  79. +NMBDOBJ = $(NMBDOBJ1) namework.o nameserv.o clientutil.o
  80.  .SUFFIXES:
  81.  .SUFFIXES: .c .o .h
  82.  
  83. @@ -521,17 +522,17 @@
  84.      @echo Linking smbrun
  85.      @$(CC) $(CFLAGS) -o smbrun smbrun.o $(LIBS)
  86.  
  87. -nmblookup: nmblookup.o nmblib.o $(UTILOBJ)  
  88. +nmblookup: nmblookup.o namequery.o nmblib.o $(UTILOBJ)  
  89.      @echo Linking nmblookup
  90. -    @$(CC) $(CFLAGS) -o nmblookup nmblookup.o nmblib.o $(UTILOBJ) $(LIBS)
  91. +    @$(CC) $(CFLAGS) -o nmblookup nmblookup.o namequery.o nmblib.o $(UTILOBJ) $(LIBS)
  92.  
  93. -nmbd: nameserv.o nmblib.o nmbsync.o $(UTILOBJ) 
  94. +nmbd: nmbd.o $(NMBDOBJ)
  95.      @echo Linking nmbd
  96. -    @$(CC) $(CFLAGS) -o nmbd nameserv.o nmblib.o nmbsync.o $(UTILOBJ) $(LIBS)
  97. +    @$(CC) $(CFLAGS) -o nmbd nmbd.o $(NMBDOBJ) $(LIBS)
  98.  
  99. -smbclient: client.o clitar.o getsmbpass.o nmblib.o $(UTILOBJ) 
  100. +smbclient: client.o clitar.o getsmbpass.o namequery.o nmblib.o $(UTILOBJ) 
  101.      @echo Linking smbclient
  102. -    @$(CC) $(CFLAGS) -o smbclient client.o clitar.o getsmbpass.o nmblib.o $(UTILOBJ) $(LIBS)
  103. +    @$(CC) $(CFLAGS) -o smbclient client.o clitar.o getsmbpass.o namequery.o nmblib.o $(UTILOBJ) $(LIBS)
  104.  
  105.  smbstatus: status.o $(PARAMOBJ) 
  106.      @echo Linking smbstatus
  107. @@ -566,6 +567,9 @@
  108.  
  109.  clean:
  110.      rm -f core *.o *~ $(PROGS)
  111. +
  112. +proto:
  113. +    cat *.c | awk -f mkproto.awk > proto.h
  114.  
  115.  realclean: clean
  116.  
  117. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/charcnv.c samba-1.9.16alpha5/source/charcnv.c
  118. --- samba-1.9.16alpha4/source/charcnv.c    Sat May  4 17:50:23 1996
  119. +++ samba-1.9.16alpha5/source/charcnv.c    Wed Jun  5 01:16:25 1996
  120. @@ -71,8 +71,7 @@
  121.  /*
  122.   * Convert unix to dos
  123.   */
  124. -char *
  125. -unix2dos_format(char *str,BOOL overwrite)
  126. +char *unix2dos_format(char *str,BOOL overwrite)
  127.  {
  128.      char *p;
  129.      char *dp;
  130. @@ -91,8 +90,7 @@
  131.  /*
  132.   * Convert dos to unix
  133.   */
  134. -char *
  135. -dos2unix_format (char *str, BOOL overwrite)
  136. +char *dos2unix_format(char *str, BOOL overwrite)
  137.  {
  138.      char *p;
  139.      char *dp;
  140. @@ -112,8 +110,7 @@
  141.  /*
  142.   * Interpret character set.
  143.   */
  144. -int 
  145. -interpret_character_set (char *str, int def)
  146. +int interpret_character_set(char *str, int def)
  147.  {
  148.  
  149.      if (strequal (str, "iso8859-1")) {
  150. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/client.c samba-1.9.16alpha5/source/client.c
  151. --- samba-1.9.16alpha4/source/client.c    Sat Jun  1 01:15:11 1996
  152. +++ samba-1.9.16alpha5/source/client.c    Wed Jun  5 01:16:26 1996
  153. @@ -24,7 +24,6 @@
  154.  #endif
  155.  
  156.  #include "includes.h"
  157. -#include "nameserv.h"
  158.  
  159.  #ifndef REGISTER
  160.  #define REGISTER 0
  161. @@ -44,6 +43,7 @@
  162.  BOOL connect_as_ipc = False;
  163.  extern struct in_addr bcast_ip;
  164.  static BOOL got_bcast=False;
  165. +struct in_addr ipzero;
  166.  
  167.  char cryptkey[8];
  168.  BOOL doencrypt=False;
  169. @@ -72,16 +72,29 @@
  170.  
  171.  BOOL translation = False;
  172.  
  173. +
  174. +static BOOL send_trans_request(char *outbuf,int trans,
  175. +                   char *name,int fid,int flags,
  176. +                   char *data,char *param,uint16 *setup,
  177. +                   int ldata,int lparam,int lsetup,
  178. +                   int mdata,int mparam,int msetup);
  179. +static BOOL receive_trans_response(char *inbuf,int trans,
  180. +                                   int *data_len,int *param_len,
  181. +                   char **data,char **param);
  182. +static int interpret_long_filename(int level,char *p,file_info *finfo);
  183. +static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir);
  184. +static int interpret_short_filename(char *p,file_info *finfo);
  185. +static BOOL call_api(int prcnt,int drcnt,
  186. +             int mprcnt,int mdrcnt,
  187. +             int *rprcnt,int *rdrcnt,
  188. +             char *param,char *data,
  189. +             char **rparam,char **rdata);
  190. +
  191. +
  192.  /* clitar bits insert */
  193. -extern void cmd_tar();
  194. -extern void cmd_block();
  195. -extern void cmd_tarmode();
  196. -extern void cmd_setmode();
  197.  extern int blocksize;
  198.  extern BOOL tar_inc;
  199.  extern BOOL tar_reset;
  200. -extern int process_tar();
  201. -extern int tar_parseargs();
  202.  /* clitar bits end */
  203.   
  204.  
  205. @@ -151,20 +164,6 @@
  206.  #define CNV_INPUT(s) unix2dos_format(s,True)
  207.  #endif
  208.  
  209. -static void send_logout(void );
  210. -BOOL reopen_connection(char *inbuf,char *outbuf);
  211. -static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
  212. -static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
  213. -static BOOL call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,
  214. -             int *rprcnt,int *rdrcnt,char *param,char *data,
  215. -             char **rparam,char **rdata);
  216. -static BOOL send_trans_request(char *outbuf,int trans,
  217. -                   char *name,int fid,int flags,
  218. -                   char *data,char *param,uint16 *setup,
  219. -                   int ldata,int lparam,int lsetup,
  220. -                   int mdata,int mparam,int msetup);
  221. -
  222. -
  223.  /****************************************************************************
  224.  setup basics in a outgoing packet
  225.  ****************************************************************************/
  226. @@ -486,6 +485,319 @@
  227.         asctime(LocalTime(&t))));
  228.  }
  229.  
  230. +
  231. +/****************************************************************************
  232. +  do a directory listing, calling fn on each file found. Use the TRANSACT2
  233. +  call for long filenames
  234. +  ****************************************************************************/
  235. +static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
  236. +{
  237. +  int max_matches = 512;
  238. +  int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
  239. +  char *p;
  240. +  pstring mask;
  241. +  file_info finfo;
  242. +  int i;
  243. +  char *dirlist = NULL;
  244. +  int dirlist_len = 0;
  245. +  int total_received = 0;
  246. +  BOOL First = True;
  247. +  char *resp_data=NULL;
  248. +  char *resp_param=NULL;
  249. +  int resp_data_len = 0;
  250. +  int resp_param_len=0;
  251. +
  252. +  int ff_resume_key = 0;
  253. +  int ff_searchcount=0;
  254. +  int ff_eos=0;
  255. +  int ff_lastname=0;
  256. +  int ff_dir_handle=0;
  257. +  int loop_count = 0;
  258. +
  259. +  uint16 setup;
  260. +  pstring param;
  261. +
  262. +  strcpy(mask,Mask);
  263. +
  264. +  while (ff_eos == 0)
  265. +    {
  266. +      loop_count++;
  267. +      if (loop_count > 200)
  268. +    {
  269. +      DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
  270. +      break;
  271. +    }
  272. +
  273. +      if (First)
  274. +    {
  275. +      setup = TRANSACT2_FINDFIRST;
  276. +      SSVAL(param,0,attribute); /* attribute */
  277. +      SSVAL(param,2,max_matches); /* max count */
  278. +      SSVAL(param,4,8+4+2);    /* resume required + close on end + continue */
  279. +      SSVAL(param,6,info_level); 
  280. +      SIVAL(param,8,0);
  281. +      strcpy(param+12,mask);
  282. +    }
  283. +      else
  284. +    {
  285. +      setup = TRANSACT2_FINDNEXT;
  286. +      SSVAL(param,0,ff_dir_handle);
  287. +      SSVAL(param,2,max_matches); /* max count */
  288. +      SSVAL(param,4,info_level); 
  289. +      SIVAL(param,6,ff_resume_key); /* ff_resume_key */
  290. +      SSVAL(param,10,8+4+2);    /* resume required + close on end + continue */
  291. +      strcpy(param+12,mask);
  292. +
  293. +      DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
  294. +           ff_dir_handle,ff_resume_key,ff_lastname,mask));
  295. +    }
  296. +      /* ??? original code added 1 pad byte after param */
  297. +
  298. +      send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
  299. +             NULL,param,&setup,
  300. +             0,12+strlen(mask)+1,1,
  301. +             BUFFER_SIZE,10,0);
  302. +
  303. +      if (!receive_trans_response(inbuf,SMBtrans2,
  304. +                  &resp_data_len,&resp_param_len,
  305. +                      &resp_data,&resp_param))
  306. +    {
  307. +      DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
  308. +      break;
  309. +    }
  310. +
  311. +      /* parse out some important return info */
  312. +      p = resp_param;
  313. +      if (First)
  314. +    {
  315. +      ff_dir_handle = SVAL(p,0);
  316. +      ff_searchcount = SVAL(p,2);
  317. +      ff_eos = SVAL(p,4);
  318. +      ff_lastname = SVAL(p,8);
  319. +    }
  320. +      else
  321. +    {
  322. +      ff_searchcount = SVAL(p,0);
  323. +      ff_eos = SVAL(p,2);
  324. +      ff_lastname = SVAL(p,6);
  325. +    }
  326. +
  327. +      if (ff_searchcount == 0) 
  328. +    break;
  329. +
  330. +      /* point to the data bytes */
  331. +      p = resp_data;
  332. +
  333. +      /* we might need the lastname for continuations */
  334. +      if (ff_lastname > 0)
  335. +    {
  336. +      switch(info_level)
  337. +        {
  338. +        case 260:
  339. +          ff_resume_key =0;
  340. +          StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
  341. +          /* strcpy(mask,p+ff_lastname+94); */
  342. +          break;
  343. +        case 1:
  344. +          strcpy(mask,p + ff_lastname + 1);
  345. +          ff_resume_key = 0;
  346. +          break;
  347. +        }
  348. +    }
  349. +      else
  350. +    strcpy(mask,"");
  351. +  
  352. +      /* and add them to the dirlist pool */
  353. +      dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
  354. +
  355. +      if (!dirlist)
  356. +    {
  357. +      DEBUG(0,("Failed to expand dirlist\n"));
  358. +      break;
  359. +    }
  360. +
  361. +      /* put in a length for the last entry, to ensure we can chain entries 
  362. +     into the next packet */
  363. +      {
  364. +    char *p2;
  365. +    for (p2=p,i=0;i<(ff_searchcount-1);i++)
  366. +      p2 += interpret_long_filename(info_level,p2,NULL);
  367. +    SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
  368. +      }
  369. +
  370. +      /* grab the data for later use */
  371. +      memcpy(dirlist+dirlist_len,p,resp_data_len);
  372. +      dirlist_len += resp_data_len;
  373. +
  374. +      total_received += ff_searchcount;
  375. +
  376. +      if (resp_data) free(resp_data); resp_data = NULL;
  377. +      if (resp_param) free(resp_param); resp_param = NULL;
  378. +
  379. +      DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
  380. +           ff_searchcount,ff_eos,ff_resume_key));
  381. +
  382. +      First = False;
  383. +    }
  384. +
  385. +  if (!fn)
  386. +    for (p=dirlist,i=0;i<total_received;i++)
  387. +      {
  388. +    p += interpret_long_filename(info_level,p,&finfo);
  389. +    display_finfo(&finfo);
  390. +      }
  391. +
  392. +  for (p=dirlist,i=0;i<total_received;i++)
  393. +    {
  394. +      p += interpret_long_filename(info_level,p,&finfo);
  395. +      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
  396. +    }
  397. +
  398. +  /* free up the dirlist buffer */
  399. +  if (dirlist) free(dirlist);
  400. +  return(total_received);
  401. +}
  402. +
  403. +
  404. +/****************************************************************************
  405. +  do a directory listing, calling fn on each file found
  406. +  ****************************************************************************/
  407. +static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
  408. +{
  409. +  char *p;
  410. +  int received = 0;
  411. +  BOOL first = True;
  412. +  char status[21];
  413. +  int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
  414. +  int num_received = 0;
  415. +  int i;
  416. +  char *dirlist = NULL;
  417. +  pstring mask;
  418. +  file_info finfo;
  419. +
  420. +  finfo = def_finfo;
  421. +
  422. +  bzero(status,21);
  423. +
  424. +  strcpy(mask,Mask);
  425. +  
  426. +  while (1)
  427. +    {
  428. +      bzero(outbuf,smb_size);
  429. +      if (first)    
  430. +    set_message(outbuf,2,5 + strlen(mask),True);
  431. +      else
  432. +    set_message(outbuf,2,5 + 21,True);
  433. +
  434. +#if FFIRST
  435. +      if (Protocol >= PROTOCOL_LANMAN1)
  436. +    CVAL(outbuf,smb_com) = SMBffirst;
  437. +      else
  438. +#endif
  439. +    CVAL(outbuf,smb_com) = SMBsearch;
  440. +
  441. +      SSVAL(outbuf,smb_tid,cnum);
  442. +      setup_pkt(outbuf);
  443. +
  444. +      SSVAL(outbuf,smb_vwv0,num_asked);
  445. +      SSVAL(outbuf,smb_vwv1,attribute);
  446. +  
  447. +      p = smb_buf(outbuf);
  448. +      *p++ = 4;
  449. +      
  450. +      if (first)
  451. +    strcpy(p,mask);
  452. +      else
  453. +    strcpy(p,"");
  454. +      p += strlen(p) + 1;
  455. +      
  456. +      *p++ = 5;
  457. +      if (first)
  458. +    SSVAL(p,0,0);
  459. +      else
  460. +    {
  461. +      SSVAL(p,0,21);
  462. +      p += 2;
  463. +      memcpy(p,status,21);
  464. +    }
  465. +
  466. +      send_smb(Client,outbuf);
  467. +      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  468. +
  469. +      received = SVAL(inbuf,smb_vwv0);
  470. +
  471. +      DEBUG(5,("dir received %d\n",received));
  472. +
  473. +      DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
  474. +
  475. +      if (received <= 0) break;
  476. +
  477. +      first = False;
  478. +
  479. +      dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
  480. +
  481. +      if (!dirlist) 
  482. +    return 0;
  483. +
  484. +      p = smb_buf(inbuf) + 3;
  485. +
  486. +      memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
  487. +         p,received*DIR_STRUCT_SIZE);
  488. +
  489. +      memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
  490. +
  491. +      num_received += received;
  492. +
  493. +      if (CVAL(inbuf,smb_rcls) != 0) break;
  494. +    }
  495. +
  496. +#if FFIRST
  497. +  if (!first && Protocol >= PROTOCOL_LANMAN1)
  498. +    {
  499. +      bzero(outbuf,smb_size);
  500. +      CVAL(outbuf,smb_com) = SMBfclose;
  501. +
  502. +      SSVAL(outbuf,smb_tid,cnum);
  503. +      setup_pkt(outbuf);
  504. +
  505. +      p = smb_buf(outbuf);
  506. +      *p++ = 4;
  507. +      
  508. +      strcpy(p,"");
  509. +      p += strlen(p) + 1;
  510. +      
  511. +      *p++ = 5;
  512. +      SSVAL(p,0,21);
  513. +      p += 2;
  514. +      memcpy(p,status,21);
  515. +
  516. +      send_smb(Client,outbuf);
  517. +      receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
  518. +
  519. +      if (CVAL(inbuf,smb_rcls) != 0) 
  520. +    DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));      
  521. +    }
  522. +#endif
  523. +
  524. +  if (!fn)
  525. +    for (p=dirlist,i=0;i<num_received;i++)
  526. +      {
  527. +    p += interpret_short_filename(p,&finfo);
  528. +    display_finfo(&finfo);
  529. +      }
  530. +
  531. +  for (p=dirlist,i=0;i<num_received;i++)
  532. +    {
  533. +      p += interpret_short_filename(p,&finfo);
  534. +      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
  535. +    }
  536. +
  537. +  if (dirlist) free(dirlist);
  538. +  return(num_received);
  539. +}
  540. +
  541. +
  542. +
  543.  /****************************************************************************
  544.    do a directory listing, calling fn on each file found
  545.    ****************************************************************************/
  546. @@ -634,199 +946,62 @@
  547.        return(ret);
  548.      }
  549.        return(SVAL(p,0));
  550. -    }
  551. -
  552. -  DEBUG(1,("Unknown long filename format %d\n",level));
  553. -  return(SVAL(p,0));
  554. -}
  555. -
  556. -
  557. -
  558. -
  559. -/****************************************************************************
  560. -  act on the files in a dir listing
  561. -  ****************************************************************************/
  562. -static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
  563. -{
  564. -
  565. -  if (!((finfo->mode & aDIR) == 0 && *fileselection && 
  566. -    !mask_match(finfo->name,fileselection,False,False)) &&
  567. -      !(recurse_dir && (strequal(finfo->name,".") || 
  568. -            strequal(finfo->name,".."))))
  569. -    {
  570. -      if (recurse_dir && (finfo->mode & aDIR))
  571. -    {
  572. -      pstring mask2;
  573. -      pstring sav_dir;
  574. -      strcpy(sav_dir,cur_dir);
  575. -      strcat(cur_dir,finfo->name);
  576. -      strcat(cur_dir,"\\");
  577. -      strcpy(mask2,cur_dir);
  578. -
  579. -      if (!fn)
  580. -        DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
  581. -
  582. -      strcat(mask2,"*");
  583. -
  584. -      if (longdir)
  585. -        do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);      
  586. -      else
  587. -        do_dir(inbuf,outbuf,mask2,attribute,fn,True);
  588. -
  589. -      strcpy(cur_dir,sav_dir);
  590. -    }
  591. -      else
  592. -    {
  593. -      if (fn && do_this_one(finfo))
  594. -        fn(finfo);
  595. -    }
  596. -    }
  597. -}
  598. -
  599. -
  600. -/****************************************************************************
  601. -  do a directory listing, calling fn on each file found
  602. -  ****************************************************************************/
  603. -static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
  604. -{
  605. -  char *p;
  606. -  int received = 0;
  607. -  BOOL first = True;
  608. -  char status[21];
  609. -  int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
  610. -  int num_received = 0;
  611. -  int i;
  612. -  char *dirlist = NULL;
  613. -  pstring mask;
  614. -  file_info finfo;
  615. -
  616. -  finfo = def_finfo;
  617. -
  618. -  bzero(status,21);
  619. -
  620. -  strcpy(mask,Mask);
  621. -  
  622. -  while (1)
  623. -    {
  624. -      bzero(outbuf,smb_size);
  625. -      if (first)    
  626. -    set_message(outbuf,2,5 + strlen(mask),True);
  627. -      else
  628. -    set_message(outbuf,2,5 + 21,True);
  629. -
  630. -#if FFIRST
  631. -      if (Protocol >= PROTOCOL_LANMAN1)
  632. -    CVAL(outbuf,smb_com) = SMBffirst;
  633. -      else
  634. -#endif
  635. -    CVAL(outbuf,smb_com) = SMBsearch;
  636. -
  637. -      SSVAL(outbuf,smb_tid,cnum);
  638. -      setup_pkt(outbuf);
  639. -
  640. -      SSVAL(outbuf,smb_vwv0,num_asked);
  641. -      SSVAL(outbuf,smb_vwv1,attribute);
  642. -  
  643. -      p = smb_buf(outbuf);
  644. -      *p++ = 4;
  645. -      
  646. -      if (first)
  647. -    strcpy(p,mask);
  648. -      else
  649. -    strcpy(p,"");
  650. -      p += strlen(p) + 1;
  651. -      
  652. -      *p++ = 5;
  653. -      if (first)
  654. -    SSVAL(p,0,0);
  655. -      else
  656. -    {
  657. -      SSVAL(p,0,21);
  658. -      p += 2;
  659. -      memcpy(p,status,21);
  660. -    }
  661. -
  662. -      send_smb(Client,outbuf);
  663. -      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  664. -
  665. -      received = SVAL(inbuf,smb_vwv0);
  666. -
  667. -      DEBUG(5,("dir received %d\n",received));
  668. -
  669. -      DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
  670. -
  671. -      if (received <= 0) break;
  672. -
  673. -      first = False;
  674. -
  675. -      dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
  676. -
  677. -      if (!dirlist) 
  678. -    return 0;
  679. +    }
  680.  
  681. -      p = smb_buf(inbuf) + 3;
  682. +  DEBUG(1,("Unknown long filename format %d\n",level));
  683. +  return(SVAL(p,0));
  684. +}
  685.  
  686. -      memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
  687. -         p,received*DIR_STRUCT_SIZE);
  688.  
  689. -      memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
  690.  
  691. -      num_received += received;
  692.  
  693. -      if (CVAL(inbuf,smb_rcls) != 0) break;
  694. -    }
  695. +/****************************************************************************
  696. +  act on the files in a dir listing
  697. +  ****************************************************************************/
  698. +static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
  699. +{
  700.  
  701. -#if FFIRST
  702. -  if (!first && Protocol >= PROTOCOL_LANMAN1)
  703. +  if (!((finfo->mode & aDIR) == 0 && *fileselection && 
  704. +    !mask_match(finfo->name,fileselection,False,False)) &&
  705. +      !(recurse_dir && (strequal(finfo->name,".") || 
  706. +            strequal(finfo->name,".."))))
  707.      {
  708. -      bzero(outbuf,smb_size);
  709. -      CVAL(outbuf,smb_com) = SMBfclose;
  710. -
  711. -      SSVAL(outbuf,smb_tid,cnum);
  712. -      setup_pkt(outbuf);
  713. -
  714. -      p = smb_buf(outbuf);
  715. -      *p++ = 4;
  716. -      
  717. -      strcpy(p,"");
  718. -      p += strlen(p) + 1;
  719. -      
  720. -      *p++ = 5;
  721. -      SSVAL(p,0,21);
  722. -      p += 2;
  723. -      memcpy(p,status,21);
  724. +      if (recurse_dir && (finfo->mode & aDIR))
  725. +    {
  726. +      pstring mask2;
  727. +      pstring sav_dir;
  728. +      strcpy(sav_dir,cur_dir);
  729. +      strcat(cur_dir,finfo->name);
  730. +      strcat(cur_dir,"\\");
  731. +      strcpy(mask2,cur_dir);
  732.  
  733. -      send_smb(Client,outbuf);
  734. -      receive_smb(Client,inbuf,CLIENT_TIMEOUT,False);
  735. +      if (!fn)
  736. +        DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
  737.  
  738. -      if (CVAL(inbuf,smb_rcls) != 0) 
  739. -    DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));      
  740. -    }
  741. -#endif
  742. +      strcat(mask2,"*");
  743.  
  744. -  if (!fn)
  745. -    for (p=dirlist,i=0;i<num_received;i++)
  746. -      {
  747. -    p += interpret_short_filename(p,&finfo);
  748. -    display_finfo(&finfo);
  749. -      }
  750. +      if (longdir)
  751. +        do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);      
  752. +      else
  753. +        do_dir(inbuf,outbuf,mask2,attribute,fn,True);
  754.  
  755. -  for (p=dirlist,i=0;i<num_received;i++)
  756. -    {
  757. -      p += interpret_short_filename(p,&finfo);
  758. -      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
  759. +      strcpy(cur_dir,sav_dir);
  760. +    }
  761. +      else
  762. +    {
  763. +      if (fn && do_this_one(finfo))
  764. +        fn(finfo);
  765. +    }
  766.      }
  767. -
  768. -  if (dirlist) free(dirlist);
  769. -  return(num_received);
  770.  }
  771.  
  772. +
  773.  /****************************************************************************
  774.    receive a SMB trans or trans2 response allocating the necessary memory
  775.    ****************************************************************************/
  776.  static BOOL receive_trans_response(char *inbuf,int trans,
  777.                                     int *data_len,int *param_len,
  778. -                      char **data,char **param)
  779. +                   char **data,char **param)
  780.  {
  781.    int total_data=0;
  782.    int total_param=0;
  783. @@ -894,178 +1069,6 @@
  784.    return(True);
  785.  }
  786.  
  787. -/****************************************************************************
  788. -  do a directory listing, calling fn on each file found. Use the TRANSACT2
  789. -  call for long filenames
  790. -  ****************************************************************************/
  791. -static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
  792. -{
  793. -  int max_matches = 512;
  794. -  int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
  795. -  char *p;
  796. -  pstring mask;
  797. -  file_info finfo;
  798. -  int i;
  799. -  char *dirlist = NULL;
  800. -  int dirlist_len = 0;
  801. -  int total_received = 0;
  802. -  BOOL First = True;
  803. -  char *resp_data=NULL;
  804. -  char *resp_param=NULL;
  805. -  int resp_data_len = 0;
  806. -  int resp_param_len=0;
  807. -
  808. -  int ff_resume_key = 0;
  809. -  int ff_searchcount=0;
  810. -  int ff_eos=0;
  811. -  int ff_lastname=0;
  812. -  int ff_dir_handle=0;
  813. -  int loop_count = 0;
  814. -
  815. -  uint16 setup;
  816. -  pstring param;
  817. -
  818. -  strcpy(mask,Mask);
  819. -
  820. -  while (ff_eos == 0)
  821. -    {
  822. -      loop_count++;
  823. -      if (loop_count > 200)
  824. -    {
  825. -      DEBUG(0,("ERROR: Looping in FIND_NEXT??\n"));
  826. -      break;
  827. -    }
  828. -
  829. -      if (First)
  830. -    {
  831. -      setup = TRANSACT2_FINDFIRST;
  832. -      SSVAL(param,0,attribute); /* attribute */
  833. -      SSVAL(param,2,max_matches); /* max count */
  834. -      SSVAL(param,4,8+4+2);    /* resume required + close on end + continue */
  835. -      SSVAL(param,6,info_level); 
  836. -      SIVAL(param,8,0);
  837. -      strcpy(param+12,mask);
  838. -    }
  839. -      else
  840. -    {
  841. -      setup = TRANSACT2_FINDNEXT;
  842. -      SSVAL(param,0,ff_dir_handle);
  843. -      SSVAL(param,2,max_matches); /* max count */
  844. -      SSVAL(param,4,info_level); 
  845. -      SIVAL(param,6,ff_resume_key); /* ff_resume_key */
  846. -      SSVAL(param,10,8+4+2);    /* resume required + close on end + continue */
  847. -      strcpy(param+12,mask);
  848. -
  849. -      DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
  850. -           ff_dir_handle,ff_resume_key,ff_lastname,mask));
  851. -    }
  852. -      /* ??? original code added 1 pad byte after param */
  853. -
  854. -      send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
  855. -             NULL,param,&setup,
  856. -             0,12+strlen(mask)+1,1,
  857. -             BUFFER_SIZE,10,0);
  858. -
  859. -      if (!receive_trans_response(inbuf,SMBtrans2,
  860. -                  &resp_data_len,&resp_param_len,
  861. -                      &resp_data,&resp_param))
  862. -    {
  863. -      DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
  864. -      break;
  865. -    }
  866. -
  867. -      /* parse out some important return info */
  868. -      p = resp_param;
  869. -      if (First)
  870. -    {
  871. -      ff_dir_handle = SVAL(p,0);
  872. -      ff_searchcount = SVAL(p,2);
  873. -      ff_eos = SVAL(p,4);
  874. -      ff_lastname = SVAL(p,8);
  875. -    }
  876. -      else
  877. -    {
  878. -      ff_searchcount = SVAL(p,0);
  879. -      ff_eos = SVAL(p,2);
  880. -      ff_lastname = SVAL(p,6);
  881. -    }
  882. -
  883. -      if (ff_searchcount == 0) 
  884. -    break;
  885. -
  886. -      /* point to the data bytes */
  887. -      p = resp_data;
  888. -
  889. -      /* we might need the lastname for continuations */
  890. -      if (ff_lastname > 0)
  891. -    {
  892. -      switch(info_level)
  893. -        {
  894. -        case 260:
  895. -          ff_resume_key =0;
  896. -          StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
  897. -          /* strcpy(mask,p+ff_lastname+94); */
  898. -          break;
  899. -        case 1:
  900. -          strcpy(mask,p + ff_lastname + 1);
  901. -          ff_resume_key = 0;
  902. -          break;
  903. -        }
  904. -    }
  905. -      else
  906. -    strcpy(mask,"");
  907. -  
  908. -      /* and add them to the dirlist pool */
  909. -      dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
  910. -
  911. -      if (!dirlist)
  912. -    {
  913. -      DEBUG(0,("Failed to expand dirlist\n"));
  914. -      break;
  915. -    }
  916. -
  917. -      /* put in a length for the last entry, to ensure we can chain entries 
  918. -     into the next packet */
  919. -      {
  920. -    char *p2;
  921. -    for (p2=p,i=0;i<(ff_searchcount-1);i++)
  922. -      p2 += interpret_long_filename(info_level,p2,NULL);
  923. -    SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
  924. -      }
  925. -
  926. -      /* grab the data for later use */
  927. -      memcpy(dirlist+dirlist_len,p,resp_data_len);
  928. -      dirlist_len += resp_data_len;
  929. -
  930. -      total_received += ff_searchcount;
  931. -
  932. -      if (resp_data) free(resp_data); resp_data = NULL;
  933. -      if (resp_param) free(resp_param); resp_param = NULL;
  934. -
  935. -      DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
  936. -           ff_searchcount,ff_eos,ff_resume_key));
  937. -
  938. -      First = False;
  939. -    }
  940. -
  941. -  if (!fn)
  942. -    for (p=dirlist,i=0;i<total_received;i++)
  943. -      {
  944. -    p += interpret_long_filename(info_level,p,&finfo);
  945. -    display_finfo(&finfo);
  946. -      }
  947. -
  948. -  for (p=dirlist,i=0;i<total_received;i++)
  949. -    {
  950. -      p += interpret_long_filename(info_level,p,&finfo);
  951. -      dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
  952. -    }
  953. -
  954. -  /* free up the dirlist buffer */
  955. -  if (dirlist) free(dirlist);
  956. -  return(total_received);
  957. -}
  958. -
  959.  
  960.  /****************************************************************************
  961.    get a directory listing
  962. @@ -3596,6 +3599,7 @@
  963.    pstring param;
  964.    int uLevel = 1;
  965.    int count = 0;
  966. +  BOOL ok = False;
  967.  
  968.    /* now send a SMBtrans command with api ServerEnum? */
  969.    p = param;
  970. @@ -3642,7 +3646,8 @@
  971.        printf("\t%-16.16s     %s\n",
  972.           sname,
  973.           comment_offset?rdata+comment_offset-converter:"");
  974. -      
  975. +
  976. +      ok=True;
  977.        p2 += 26;
  978.      }
  979.        }
  980. @@ -3680,6 +3685,7 @@
  981.           sname,
  982.           comment_offset?rdata+comment_offset-converter:"");
  983.        
  984. +      ok=True;
  985.        p2 += 26;
  986.      }
  987.        }
  988. @@ -3688,7 +3694,7 @@
  989.    if (rparam) free(rparam);
  990.    if (rdata) free(rdata);
  991.  
  992. -  return(count>0);
  993. +  return(ok);
  994.  }
  995.  
  996.  
  997. @@ -3999,7 +4005,7 @@
  998.  /****************************************************************************
  999.    process commands from the client
  1000.  ****************************************************************************/
  1001. -BOOL process(char *base_directory)
  1002. +static BOOL process(char *base_directory)
  1003.  {
  1004.    extern FILE *dbf;
  1005.    pstring line;
  1006. @@ -4115,7 +4121,7 @@
  1007.  /****************************************************************************
  1008.  usage on the program
  1009.  ****************************************************************************/
  1010. -void usage(char *pname)
  1011. +static void usage(char *pname)
  1012.  {
  1013.    DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
  1014.         pname));
  1015. @@ -4152,11 +4158,11 @@
  1016.  /****************************************************************************
  1017.    main program
  1018.  ****************************************************************************/
  1019. -int main(int argc,char *argv[])
  1020. + int main(int argc,char *argv[])
  1021.  {
  1022.    fstring base_directory;
  1023.    char *pname = argv[0];
  1024. -  int port = 139;
  1025. +  int port = SMB_PORT;
  1026.    int opt;
  1027.    extern FILE *dbf;
  1028.    extern char *optarg;
  1029. @@ -4174,6 +4180,8 @@
  1030.  
  1031.    TimeInit();
  1032.    charset_initialise();
  1033. +
  1034. +  ipzero = *interpret_addr2("0.0.0.0");
  1035.  
  1036.    pid = getpid();
  1037.    uid = getuid();
  1038. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/clientutil.c samba-1.9.16alpha5/source/clientutil.c
  1039. --- samba-1.9.16alpha4/source/clientutil.c    Thu Jan  1 10:00:00 1970
  1040. +++ samba-1.9.16alpha5/source/clientutil.c    Tue Jun  4 16:41:07 1996
  1041. @@ -0,0 +1,1029 @@
  1042. +/* 
  1043. +   Unix SMB/Netbios implementation.
  1044. +   Version 1.9.
  1045. +   SMB client
  1046. +   Copyright (C) Andrew Tridgell 1994-1995
  1047. +   
  1048. +   This program is free software; you can redistribute it and/or modify
  1049. +   it under the terms of the GNU General Public License as published by
  1050. +   the Free Software Foundation; either version 2 of the License, or
  1051. +   (at your option) any later version.
  1052. +   
  1053. +   This program is distributed in the hope that it will be useful,
  1054. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1055. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1056. +   GNU General Public License for more details.
  1057. +   
  1058. +   You should have received a copy of the GNU General Public License
  1059. +   along with this program; if not, write to the Free Software
  1060. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1061. +*/
  1062. +
  1063. +#ifdef SYSLOG
  1064. +#undef SYSLOG
  1065. +#endif
  1066. +
  1067. +#include "includes.h"
  1068. +
  1069. +#ifndef REGISTER
  1070. +#define REGISTER 0
  1071. +#endif
  1072. +
  1073. +pstring service="";
  1074. +pstring desthost="";
  1075. +pstring myname = "";
  1076. +pstring password = "";
  1077. +pstring username="";
  1078. +pstring workgroup=WORKGROUP;
  1079. +BOOL got_pass = False;
  1080. +BOOL connect_as_printer = False;
  1081. +BOOL connect_as_ipc = False;
  1082. +
  1083. +char cryptkey[8];
  1084. +BOOL doencrypt=False;
  1085. +
  1086. +extern pstring user_socket_options;
  1087. +
  1088. +/* 30 second timeout on most commands */
  1089. +#define CLIENT_TIMEOUT (30*1000)
  1090. +#define SHORT_TIMEOUT (5*1000)
  1091. +
  1092. +int name_type = 0x20;
  1093. +
  1094. +int max_protocol = PROTOCOL_NT1;
  1095. +
  1096. +BOOL readbraw_supported = False;
  1097. +BOOL writebraw_supported = False;
  1098. +
  1099. +extern int DEBUGLEVEL;
  1100. +
  1101. +int cnum = 0;
  1102. +int pid = 0;
  1103. +int gid = 0;
  1104. +int uid = 0;
  1105. +int mid = 0;
  1106. +
  1107. +int max_xmit = BUFFER_SIZE;
  1108. +
  1109. +BOOL have_ip = False;
  1110. +
  1111. +struct in_addr dest_ip;
  1112. +
  1113. +extern int Protocol;
  1114. +
  1115. +extern int Client;
  1116. +
  1117. +
  1118. +/****************************************************************************
  1119. +setup basics in a outgoing packet
  1120. +****************************************************************************/
  1121. +void cli_setup_pkt(char *outbuf)
  1122. +{
  1123. +  SSVAL(outbuf,smb_pid,pid);
  1124. +  SSVAL(outbuf,smb_uid,uid);
  1125. +  SSVAL(outbuf,smb_mid,mid);
  1126. +  if (Protocol > PROTOCOL_CORE)
  1127. +    {
  1128. +      SCVAL(outbuf,smb_flg,0x8);
  1129. +      SSVAL(outbuf,smb_flg2,0x1);
  1130. +    }
  1131. +}
  1132. +
  1133. +/****************************************************************************
  1134. +  receive a SMB trans or trans2 response allocating the necessary memory
  1135. +  ****************************************************************************/
  1136. +BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
  1137. +                int *param_len, char **data,char **param)
  1138. +{
  1139. +  int total_data=0;
  1140. +  int total_param=0;
  1141. +  int this_data,this_param;
  1142. +
  1143. +  *data_len = *param_len = 0;
  1144. +
  1145. +  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  1146. +  show_msg(inbuf);
  1147. +
  1148. +  /* sanity check */
  1149. +  if (CVAL(inbuf,smb_com) != trans)
  1150. +    {
  1151. +      DEBUG(0,("Expected %s response, got command 0x%02x\n",
  1152. +           trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
  1153. +      return(False);
  1154. +    }
  1155. +  if (CVAL(inbuf,smb_rcls) != 0)
  1156. +    return(False);
  1157. +
  1158. +  /* parse out the lengths */
  1159. +  total_data = SVAL(inbuf,smb_tdrcnt);
  1160. +  total_param = SVAL(inbuf,smb_tprcnt);
  1161. +
  1162. +  /* allocate it */
  1163. +  *data = Realloc(*data,total_data);
  1164. +  *param = Realloc(*param,total_param);
  1165. +
  1166. +  while (1)
  1167. +    {
  1168. +      this_data = SVAL(inbuf,smb_drcnt);
  1169. +      this_param = SVAL(inbuf,smb_prcnt);
  1170. +      if (this_data)
  1171. +    memcpy(*data + SVAL(inbuf,smb_drdisp),
  1172. +           smb_base(inbuf) + SVAL(inbuf,smb_droff),
  1173. +           this_data);
  1174. +      if (this_param)
  1175. +    memcpy(*param + SVAL(inbuf,smb_prdisp),
  1176. +           smb_base(inbuf) + SVAL(inbuf,smb_proff),
  1177. +           this_param);
  1178. +      *data_len += this_data;
  1179. +      *param_len += this_param;
  1180. +
  1181. +      /* parse out the total lengths again - they can shrink! */
  1182. +      total_data = SVAL(inbuf,smb_tdrcnt);
  1183. +      total_param = SVAL(inbuf,smb_tprcnt);
  1184. +
  1185. +      if (total_data <= *data_len && total_param <= *param_len)
  1186. +    break;
  1187. +
  1188. +      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  1189. +      show_msg(inbuf);
  1190. +
  1191. +      /* sanity check */
  1192. +      if (CVAL(inbuf,smb_com) != trans)
  1193. +    {
  1194. +      DEBUG(0,("Expected %s response, got command 0x%02x\n",
  1195. +           trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
  1196. +      return(False);
  1197. +    }
  1198. +      if (CVAL(inbuf,smb_rcls) != 0)
  1199. +      return(False);
  1200. +    }
  1201. +  
  1202. +  return(True);
  1203. +}
  1204. +
  1205. +/****************************************************************************
  1206. +send a session request
  1207. +****************************************************************************/
  1208. +BOOL cli_send_session_request(char *inbuf, char *outbuf)
  1209. +{
  1210. +  fstring dest;
  1211. +  char *p;
  1212. +  int len = 4;
  1213. +  /* send a session request (RFC 8002) */
  1214. +
  1215. +  strcpy(dest,desthost);
  1216. +  p = strchr(dest,'.');
  1217. +  if (p) *p = 0;
  1218. +
  1219. +  /* put in the destination name */
  1220. +  p = outbuf+len;
  1221. +  name_mangle(dest,p,name_type);
  1222. +  len += name_len(p);
  1223. +
  1224. +  /* and my name */
  1225. +  p = outbuf+len;
  1226. +  name_mangle(myname,p,0);
  1227. +  len += name_len(p);
  1228. +
  1229. +  /* setup the packet length */
  1230. +  _smb_setlen(outbuf,len);
  1231. +  CVAL(outbuf,0) = 0x81;
  1232. +
  1233. +  send_smb(Client,outbuf);
  1234. +  DEBUG(5,("Sent session request\n"));
  1235. +
  1236. +  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  1237. +
  1238. +  if (CVAL(inbuf,0) == 0x84) /* C. Hoch  9/14/95 Start */
  1239. +    {
  1240. +      /* For information, here is the response structure.
  1241. +       * We do the byte-twiddling to for portability.
  1242. +       struct RetargetResponse{
  1243. +       unsigned char type;
  1244. +       unsigned char flags;
  1245. +       int16 length;
  1246. +       int32 ip_addr;
  1247. +       int16 port;
  1248. +       };
  1249. +       */
  1250. +      extern int Client;
  1251. +      int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
  1252. +      /* SESSION RETARGET */
  1253. +      putip((char *)&dest_ip,inbuf+4);
  1254. +
  1255. +      close_sockets();
  1256. +      Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
  1257. +      if (Client == -1)
  1258. +        return False;
  1259. +
  1260. +      DEBUG(3,("Retargeted\n"));
  1261. +
  1262. +      set_socket_options(Client,user_socket_options);
  1263. +
  1264. +      /* Try again */
  1265. +      return cli_send_session_request(inbuf,outbuf);
  1266. +    } /* C. Hoch 9/14/95 End */
  1267. +
  1268. +
  1269. +  if (CVAL(inbuf,0) != 0x82)
  1270. +    {
  1271. +      int ecode = CVAL(inbuf,4);
  1272. +      DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
  1273. +           CVAL(inbuf,0),ecode,myname,desthost));
  1274. +      switch (ecode)
  1275. +    {
  1276. +    case 0x80: 
  1277. +      DEBUG(0,("Not listening on called name\n")); 
  1278. +      DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
  1279. +      DEBUG(0,("You may find the -I option useful for this\n"));
  1280. +      break;
  1281. +    case 0x81: 
  1282. +      DEBUG(0,("Not listening for calling name\n")); 
  1283. +      DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
  1284. +      DEBUG(0,("You may find the -n option useful for this\n"));
  1285. +      break;
  1286. +    case 0x82: 
  1287. +      DEBUG(0,("Called name not present\n")); 
  1288. +      DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
  1289. +      DEBUG(0,("You may find the -I option useful for this\n"));
  1290. +      break;
  1291. +    case 0x83: 
  1292. +      DEBUG(0,("Called name present, but insufficient resources\n")); 
  1293. +      DEBUG(0,("Perhaps you should try again later?\n")); 
  1294. +      break;
  1295. +    default:
  1296. +      DEBUG(0,("Unspecified error 0x%X\n",ecode)); 
  1297. +      DEBUG(0,("Your server software is being unfriendly\n"));
  1298. +      break;      
  1299. +    }
  1300. +      return(False);
  1301. +    }
  1302. +  return(True);
  1303. +}
  1304. +
  1305. +
  1306. +static  struct {
  1307. +    int prot;
  1308. +    char *name;
  1309. +  }
  1310. +prots[] = 
  1311. +    {
  1312. +      {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
  1313. +      {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
  1314. +      {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
  1315. +      {PROTOCOL_LANMAN1,"LANMAN1.0"},
  1316. +      {PROTOCOL_LANMAN2,"LM1.2X002"},
  1317. +      {PROTOCOL_LANMAN2,"Samba"},
  1318. +      {PROTOCOL_NT1,"NT LM 0.12"},
  1319. +      {PROTOCOL_NT1,"NT LANMAN 1.0"},
  1320. +      {-1,NULL}
  1321. +    };
  1322. +
  1323. +/****************************************************************************
  1324. +send a login command
  1325. +****************************************************************************/
  1326. +BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup)
  1327. +{
  1328. +  BOOL was_null = (!inbuf && !outbuf);
  1329. +  int sesskey=0;
  1330. +  time_t servertime = 0;
  1331. +  extern int serverzone;
  1332. +  int sec_mode=0;
  1333. +  int crypt_len;
  1334. +  int max_vcs=0;
  1335. +  char *pass = NULL;  
  1336. +  pstring dev;
  1337. +  char *p;
  1338. +  int numprots;
  1339. +
  1340. +  if (was_null)
  1341. +    {
  1342. +      inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  1343. +      outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  1344. +    }
  1345. +
  1346. +  strcpy(dev,"A:");
  1347. +  if (connect_as_printer)
  1348. +    strcpy(dev,"LPT1:");
  1349. +  if (connect_as_ipc)
  1350. +    strcpy(dev,"IPC");
  1351. +
  1352. +
  1353. +  if (start_session && !cli_send_session_request(inbuf,outbuf))
  1354. +    {
  1355. +      if (was_null)
  1356. +    {
  1357. +      free(inbuf);
  1358. +      free(outbuf);
  1359. +    }      
  1360. +      return(False);
  1361. +    }
  1362. +
  1363. +  bzero(outbuf,smb_size);
  1364. +
  1365. +  /* setup the protocol strings */
  1366. +  {
  1367. +    int plength;
  1368. +
  1369. +    for (plength=0,numprots=0;
  1370. +     prots[numprots].name && prots[numprots].prot<=max_protocol;
  1371. +     numprots++)
  1372. +      plength += strlen(prots[numprots].name)+2;
  1373. +    
  1374. +    set_message(outbuf,0,plength,True);
  1375. +
  1376. +    p = smb_buf(outbuf);
  1377. +    for (numprots=0;
  1378. +     prots[numprots].name && prots[numprots].prot<=max_protocol;
  1379. +     numprots++)
  1380. +      {
  1381. +    *p++ = 2;
  1382. +    strcpy(p,prots[numprots].name);
  1383. +    p += strlen(p) + 1;
  1384. +      }
  1385. +  }
  1386. +
  1387. +  CVAL(outbuf,smb_com) = SMBnegprot;
  1388. +  cli_setup_pkt(outbuf);
  1389. +
  1390. +  CVAL(smb_buf(outbuf),0) = 2;
  1391. +
  1392. +  send_smb(Client,outbuf);
  1393. +  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  1394. +
  1395. +  show_msg(inbuf);
  1396. +
  1397. +  if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
  1398. +    {
  1399. +      DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
  1400. +        myname,desthost,smb_errstr(inbuf)));
  1401. +      if (was_null)
  1402. +    {
  1403. +      free(inbuf);
  1404. +      free(outbuf);
  1405. +    }
  1406. +      return(False);
  1407. +    }
  1408. +
  1409. +  Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
  1410. +
  1411. +
  1412. +  if (Protocol < PROTOCOL_NT1) {    
  1413. +    sec_mode = SVAL(inbuf,smb_vwv1);
  1414. +    max_xmit = SVAL(inbuf,smb_vwv2);
  1415. +    sesskey = IVAL(inbuf,smb_vwv6);
  1416. +    serverzone = SVALS(inbuf,smb_vwv10)*60;
  1417. +    /* this time is converted to GMT by make_unix_date */
  1418. +    servertime = make_unix_date(inbuf+smb_vwv8);
  1419. +    if (Protocol >= PROTOCOL_COREPLUS) {
  1420. +      readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
  1421. +      writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
  1422. +    }
  1423. +    crypt_len = smb_buflen(inbuf);
  1424. +    memcpy(cryptkey,smb_buf(inbuf),8);
  1425. +    DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
  1426. +    max_vcs = SVAL(inbuf,smb_vwv4); 
  1427. +    DEBUG(3,("max vcs %d\n",max_vcs)); 
  1428. +    DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
  1429. +  } else {
  1430. +    /* NT protocol */
  1431. +    sec_mode = CVAL(inbuf,smb_vwv1);
  1432. +    max_xmit = IVAL(inbuf,smb_vwv3+1);
  1433. +    sesskey = IVAL(inbuf,smb_vwv7+1);
  1434. +    serverzone = SVALS(inbuf,smb_vwv15+1)*60;
  1435. +    /* this time arrives in real GMT */
  1436. +    servertime = interpret_long_date(inbuf+smb_vwv11+1);
  1437. +    crypt_len = CVAL(inbuf,smb_vwv16+1);
  1438. +    memcpy(cryptkey,smb_buf(inbuf),8);
  1439. +    if (IVAL(inbuf,smb_vwv9+1) & 1)
  1440. +      readbraw_supported = writebraw_supported = True;      
  1441. +    DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
  1442. +    max_vcs = SVAL(inbuf,smb_vwv2+1); 
  1443. +    DEBUG(3,("max vcs %d\n",max_vcs));
  1444. +    DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
  1445. +    DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
  1446. +  }
  1447. +
  1448. +  DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
  1449. +  DEBUG(3,("max xmt %d\n",max_xmit));
  1450. +  DEBUG(3,("Got %d byte crypt key\n",crypt_len));
  1451. +  DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
  1452. +
  1453. +  doencrypt = ((sec_mode & 2) != 0);
  1454. +
  1455. +  if (servertime) {
  1456. +    static BOOL done_time = False;
  1457. +    if (!done_time) {
  1458. +      DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
  1459. +           asctime(LocalTime(&servertime)),
  1460. +           -(double)(serverzone/3600.0)));
  1461. +      done_time = True;
  1462. +    }
  1463. +  }
  1464. +
  1465. + get_pass:
  1466. +
  1467. +  if (got_pass)
  1468. +    pass = password;
  1469. +  else
  1470. +    pass = (char *)getpass("Password: ");
  1471. +
  1472. +  if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
  1473. +    {
  1474. +      fstring pword;
  1475. +      int passlen = strlen(pass)+1;
  1476. +      strcpy(pword,pass);      
  1477. +
  1478. +#ifdef SMB_PASSWD
  1479. +      if (doencrypt && *pass) {
  1480. +    DEBUG(3,("Using encrypted passwords\n"));
  1481. +    passlen = 24;
  1482. +    SMBencrypt(pass,cryptkey,pword);
  1483. +      }
  1484. +#else
  1485. +      doencrypt = False;
  1486. +#endif
  1487. +
  1488. +      /* if in share level security then don't send a password now */
  1489. +      if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;} 
  1490. +
  1491. +      /* send a session setup command */
  1492. +      bzero(outbuf,smb_size);
  1493. +
  1494. +      if (Protocol < PROTOCOL_NT1) {
  1495. +    set_message(outbuf,10,1 + strlen(username) + passlen,True);
  1496. +    CVAL(outbuf,smb_com) = SMBsesssetupX;
  1497. +    cli_setup_pkt(outbuf);
  1498. +
  1499. +    CVAL(outbuf,smb_vwv0) = 0xFF;
  1500. +    SSVAL(outbuf,smb_vwv2,max_xmit);
  1501. +    SSVAL(outbuf,smb_vwv3,2);
  1502. +    SSVAL(outbuf,smb_vwv4,max_vcs-1);
  1503. +    SIVAL(outbuf,smb_vwv5,sesskey);
  1504. +    SSVAL(outbuf,smb_vwv7,passlen);
  1505. +    p = smb_buf(outbuf);
  1506. +    memcpy(p,pword,passlen);
  1507. +    p += passlen;
  1508. +    strcpy(p,username);
  1509. +      } else {
  1510. +    if (!doencrypt) passlen--;
  1511. +    /* for Win95 */
  1512. +    set_message(outbuf,13,0,True);
  1513. +    CVAL(outbuf,smb_com) = SMBsesssetupX;
  1514. +    cli_setup_pkt(outbuf);
  1515. +
  1516. +    CVAL(outbuf,smb_vwv0) = 0xFF;
  1517. +    SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
  1518. +    SSVAL(outbuf,smb_vwv3,2);
  1519. +    SSVAL(outbuf,smb_vwv4,getpid());
  1520. +    SIVAL(outbuf,smb_vwv5,sesskey);
  1521. +    SSVAL(outbuf,smb_vwv7,passlen);
  1522. +    SSVAL(outbuf,smb_vwv8,0);
  1523. +    p = smb_buf(outbuf);
  1524. +    memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
  1525. +    strcpy(p,username);p = skip_string(p,1);
  1526. +    strcpy(p,workgroup);p = skip_string(p,1);
  1527. +    strcpy(p,"Unix");p = skip_string(p,1);
  1528. +    strcpy(p,"Samba");p = skip_string(p,1);
  1529. +    set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
  1530. +      }
  1531. +
  1532. +      send_smb(Client,outbuf);
  1533. +      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  1534. +
  1535. +      show_msg(inbuf);
  1536. +
  1537. +      if (CVAL(inbuf,smb_rcls) != 0)
  1538. +    {
  1539. +      if (! *pass &&
  1540. +          ((CVAL(inbuf,smb_rcls) == ERRDOS && 
  1541. +        SVAL(inbuf,smb_err) == ERRnoaccess) ||
  1542. +           (CVAL(inbuf,smb_rcls) == ERRSRV && 
  1543. +        SVAL(inbuf,smb_err) == ERRbadpw)))
  1544. +        {
  1545. +          got_pass = False;
  1546. +          DEBUG(3,("resending login\n"));
  1547. +          goto get_pass;
  1548. +        }
  1549. +          
  1550. +      DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s   %s\n",
  1551. +        username,myname,desthost,smb_errstr(inbuf)));
  1552. +      DEBUG(0,("You might find the -U or -n options useful\n"));
  1553. +      DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
  1554. +      DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
  1555. +      if (was_null)
  1556. +        {
  1557. +          free(inbuf);
  1558. +          free(outbuf);
  1559. +        }
  1560. +      return(False);
  1561. +    }
  1562. +
  1563. +      if (Protocol >= PROTOCOL_NT1) {
  1564. +    char *domain,*os,*lanman;
  1565. +    p = smb_buf(inbuf);
  1566. +    os = p;
  1567. +    lanman = skip_string(os,1);
  1568. +    domain = skip_string(lanman,1);
  1569. +    if (*domain || *os || *lanman)
  1570. +      DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
  1571. +      }
  1572. +
  1573. +      /* use the returned uid from now on */
  1574. +      if (SVAL(inbuf,smb_uid) != uid)
  1575. +    DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
  1576. +          SVAL(inbuf,smb_uid),uid));
  1577. +      uid = SVAL(inbuf,smb_uid);
  1578. +    }
  1579. +
  1580. +  /* now we've got a connection - send a tcon message */
  1581. +  bzero(outbuf,smb_size);
  1582. +
  1583. +  if (strncmp(service,"\\\\",2) != 0)
  1584. +    {
  1585. +      DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
  1586. +      DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
  1587. +    }
  1588. +
  1589. +
  1590. + again2:
  1591. +
  1592. +  {
  1593. +    int passlen = strlen(pass)+1;
  1594. +    fstring pword;
  1595. +    strcpy(pword,pass);
  1596. +
  1597. +#ifdef SMB_PASSWD
  1598. +    if (doencrypt && *pass) {
  1599. +      passlen=24;
  1600. +      SMBencrypt(pass,cryptkey,pword);      
  1601. +    }
  1602. +#endif
  1603. +
  1604. +    /* if in user level security then don't send a password now */
  1605. +    if ((sec_mode & 1)) {
  1606. +      strcpy(pword, ""); passlen=1; 
  1607. +    }
  1608. +
  1609. +    set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
  1610. +    CVAL(outbuf,smb_com) = SMBtconX;
  1611. +    cli_setup_pkt(outbuf);
  1612. +
  1613. +    SSVAL(outbuf,smb_vwv0,0xFF);
  1614. +    SSVAL(outbuf,smb_vwv3,passlen);
  1615. +
  1616. +    p = smb_buf(outbuf);
  1617. +    memcpy(p,pword,passlen);
  1618. +    p += passlen;
  1619. +    strcpy(p,service);
  1620. +    p = skip_string(p,1);
  1621. +    strcpy(p,dev);
  1622. +  }
  1623. +
  1624. +  send_smb(Client,outbuf);
  1625. +  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  1626. +
  1627. +  /* trying again with a blank password */
  1628. +  if (CVAL(inbuf,smb_rcls) != 0 && 
  1629. +      (int)strlen(pass) > 0 && 
  1630. +      !doencrypt &&
  1631. +      Protocol >= PROTOCOL_LANMAN1)
  1632. +    {
  1633. +      DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
  1634. +      strcpy(pass,"");
  1635. +      goto again2;
  1636. +    }  
  1637. +
  1638. +  if (CVAL(inbuf,smb_rcls) != 0)
  1639. +    {
  1640. +      DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
  1641. +      DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
  1642. +      DEBUG(0,("Some servers insist that these be in uppercase\n"));
  1643. +      if (was_null)
  1644. +    {
  1645. +      free(inbuf);
  1646. +      free(outbuf);
  1647. +    }
  1648. +      return(False);
  1649. +    }
  1650. +  
  1651. +
  1652. +  max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
  1653. +  if (max_xmit <= 0)
  1654. +    max_xmit = BUFFER_SIZE - 4;
  1655. +
  1656. +  cnum = SVAL(inbuf,smb_tid);
  1657. +
  1658. +  DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
  1659. +
  1660. +  if (was_null)
  1661. +    {
  1662. +      free(inbuf);
  1663. +      free(outbuf);
  1664. +    }
  1665. +  return True;
  1666. +}
  1667. +
  1668. +
  1669. +/****************************************************************************
  1670. +send a logout command
  1671. +****************************************************************************/
  1672. +void cli_send_logout(void)
  1673. +{
  1674. +  pstring inbuf,outbuf;
  1675. +
  1676. +  bzero(outbuf,smb_size);
  1677. +  set_message(outbuf,0,0,True);
  1678. +  CVAL(outbuf,smb_com) = SMBtdis;
  1679. +  SSVAL(outbuf,smb_tid,cnum);
  1680. +  cli_setup_pkt(outbuf);
  1681. +
  1682. +  send_smb(Client,outbuf);
  1683. +  receive_smb(Client,inbuf,SHORT_TIMEOUT);
  1684. +
  1685. +  if (CVAL(inbuf,smb_rcls) != 0)
  1686. +    {
  1687. +      DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
  1688. +    }
  1689. +
  1690. +  
  1691. +#ifdef STATS
  1692. +  stats_report();
  1693. +#endif
  1694. +  exit(0);
  1695. +}
  1696. +
  1697. +
  1698. +
  1699. +/****************************************************************************
  1700. +call a remote api
  1701. +****************************************************************************/
  1702. +BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
  1703. +          int *rdrcnt, char *param,char *data, char **rparam,char **rdata)
  1704. +{
  1705. +  static char *inbuf=NULL;
  1706. +  static char *outbuf=NULL;
  1707. +
  1708. +  if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  1709. +  if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  1710. +
  1711. +  cli_send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
  1712. +             data,param,NULL,
  1713. +             drcnt,prcnt,0,
  1714. +             mdrcnt,mprcnt,0);
  1715. +
  1716. +  return (cli_receive_trans_response(inbuf,SMBtrans,
  1717. +                     rdrcnt,rprcnt,
  1718. +                     rdata,rparam));
  1719. +}
  1720. +
  1721. +/****************************************************************************
  1722. +  send a SMB trans or trans2 request
  1723. +  ****************************************************************************/
  1724. +BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags,
  1725. +            char *data,char *param,uint16 *setup, int ldata,int lparam,
  1726. +            int lsetup,int mdata,int mparam,int msetup)
  1727. +{
  1728. +  int i;
  1729. +  int this_ldata,this_lparam;
  1730. +  int tot_data=0,tot_param=0;
  1731. +  char *outdata,*outparam;
  1732. +  pstring inbuf;
  1733. +  char *p;
  1734. +
  1735. +  this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
  1736. +  this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
  1737. +
  1738. +  bzero(outbuf,smb_size);
  1739. +  set_message(outbuf,14+lsetup,0,True);
  1740. +  CVAL(outbuf,smb_com) = trans;
  1741. +  SSVAL(outbuf,smb_tid,cnum);
  1742. +  cli_setup_pkt(outbuf);
  1743. +
  1744. +  outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
  1745. +  outdata = outparam+this_lparam;
  1746. +
  1747. +  /* primary request */
  1748. +  SSVAL(outbuf,smb_tpscnt,lparam);    /* tpscnt */
  1749. +  SSVAL(outbuf,smb_tdscnt,ldata);    /* tdscnt */
  1750. +  SSVAL(outbuf,smb_mprcnt,mparam);    /* mprcnt */
  1751. +  SSVAL(outbuf,smb_mdrcnt,mdata);    /* mdrcnt */
  1752. +  SCVAL(outbuf,smb_msrcnt,msetup);    /* msrcnt */
  1753. +  SSVAL(outbuf,smb_flags,flags);    /* flags */
  1754. +  SIVAL(outbuf,smb_timeout,0);        /* timeout */
  1755. +  SSVAL(outbuf,smb_pscnt,this_lparam);    /* pscnt */
  1756. +  SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
  1757. +  SSVAL(outbuf,smb_dscnt,this_ldata);    /* dscnt */
  1758. +  SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
  1759. +  SCVAL(outbuf,smb_suwcnt,lsetup);    /* suwcnt */
  1760. +  for (i=0;i<lsetup;i++)        /* setup[] */
  1761. +    SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
  1762. +  p = smb_buf(outbuf);
  1763. +  if (trans==SMBtrans)
  1764. +    strcpy(p,name);            /* name[] */
  1765. +  else
  1766. +    {
  1767. +      *p++ = 0;                /* put in a null smb_name */
  1768. +      *p++ = 'D'; *p++ = ' ';        /* this was added because OS/2 does it */
  1769. +    }
  1770. +  if (this_lparam)            /* param[] */
  1771. +    memcpy(outparam,param,this_lparam);
  1772. +  if (this_ldata)            /* data[] */
  1773. +    memcpy(outdata,data,this_ldata);
  1774. +  set_message(outbuf,14+lsetup,        /* wcnt, bcc */
  1775. +          PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
  1776. +
  1777. +  show_msg(outbuf);
  1778. +  send_smb(Client,outbuf);
  1779. +
  1780. +  if (this_ldata < ldata || this_lparam < lparam)
  1781. +    {
  1782. +      /* receive interim response */
  1783. +      if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
  1784. +    {
  1785. +      DEBUG(0,("%s request failed (%s)\n",
  1786. +               trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
  1787. +      return(False);
  1788. +    }      
  1789. +
  1790. +      tot_data = this_ldata;
  1791. +      tot_param = this_lparam;
  1792. +
  1793. +      while (tot_data < ldata || tot_param < lparam)
  1794. +    {
  1795. +      this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
  1796. +      this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
  1797. +
  1798. +      set_message(outbuf,trans==SMBtrans?8:9,0,True);
  1799. +      CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
  1800. +
  1801. +      outparam = smb_buf(outbuf);
  1802. +      outdata = outparam+this_lparam;
  1803. +
  1804. +      /* secondary request */
  1805. +      SSVAL(outbuf,smb_tpscnt,lparam);    /* tpscnt */
  1806. +      SSVAL(outbuf,smb_tdscnt,ldata);    /* tdscnt */
  1807. +      SSVAL(outbuf,smb_spscnt,this_lparam);    /* pscnt */
  1808. +      SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
  1809. +      SSVAL(outbuf,smb_spsdisp,tot_param);    /* psdisp */
  1810. +      SSVAL(outbuf,smb_sdscnt,this_ldata);    /* dscnt */
  1811. +      SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
  1812. +      SSVAL(outbuf,smb_sdsdisp,tot_data);    /* dsdisp */
  1813. +      if (trans==SMBtrans2)
  1814. +        SSVAL(outbuf,smb_sfid,fid);        /* fid */
  1815. +      if (this_lparam)            /* param[] */
  1816. +        memcpy(outparam,param,this_lparam);
  1817. +      if (this_ldata)            /* data[] */
  1818. +        memcpy(outdata,data,this_ldata);
  1819. +      set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
  1820. +              PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
  1821. +
  1822. +      show_msg(outbuf);
  1823. +      send_smb(Client,outbuf);
  1824. +
  1825. +      tot_data += this_ldata;
  1826. +      tot_param += this_lparam;
  1827. +    }
  1828. +    }
  1829. +
  1830. +    return(True);
  1831. +}
  1832. +
  1833. +
  1834. +/****************************************************************************
  1835. +open the client sockets
  1836. +****************************************************************************/
  1837. +BOOL cli_open_sockets(int port)
  1838. +{
  1839. +  static int last_port;
  1840. +  char *host;
  1841. +  pstring service2;
  1842. +  extern int Client;
  1843. +
  1844. +  if (port == 0) port=last_port;
  1845. +  last_port=port;
  1846. +
  1847. +  strupper(service);
  1848. +
  1849. +  if (*desthost)
  1850. +    {
  1851. +      host = desthost;
  1852. +    }
  1853. +  else
  1854. +    {
  1855. +      strcpy(service2,service);
  1856. +      host = strtok(service2,"\\/");
  1857. +      strcpy(desthost,host);
  1858. +    }
  1859. +
  1860. +  DEBUG(3,("Opening sockets\n"));
  1861. +
  1862. +  if (*myname == 0)
  1863. +    {
  1864. +      get_myname(myname,NULL);
  1865. +      strupper(myname);
  1866. +    }
  1867. +
  1868. +  if (!have_ip)
  1869. +    {
  1870. +      struct hostent *hp;
  1871. +
  1872. +      if ((hp = Get_Hostbyname(host)) == 0) 
  1873. +    {
  1874. +      DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
  1875. +      return False;
  1876. +    }
  1877. +
  1878. +      putip((char *)&dest_ip,(char *)hp->h_addr);
  1879. +    }
  1880. +
  1881. +  Client = open_socket_out(SOCK_STREAM, &dest_ip, port);
  1882. +  if (Client == -1)
  1883. +    return False;
  1884. +
  1885. +  DEBUG(3,("Connected\n"));
  1886. +
  1887. +  set_socket_options(Client,user_socket_options);  
  1888. +
  1889. +  return True;
  1890. +}
  1891. +
  1892. +/****************************************************************************
  1893. +close and open the connection again
  1894. +****************************************************************************/
  1895. +BOOL cli_reopen_connection(char *inbuf,char *outbuf)
  1896. +{
  1897. +  static int open_count=0;
  1898. +
  1899. +  open_count++;
  1900. +
  1901. +  if (open_count>5) return(False);
  1902. +
  1903. +  DEBUG(1,("Trying to re-open connection\n"));
  1904. +
  1905. +  set_message(outbuf,0,0,True);
  1906. +  SCVAL(outbuf,smb_com,SMBtdis);
  1907. +  SSVAL(outbuf,smb_tid,cnum);
  1908. +  cli_setup_pkt(outbuf);
  1909. +
  1910. +  send_smb(Client,outbuf);
  1911. +  receive_smb(Client,inbuf,SHORT_TIMEOUT);
  1912. +
  1913. +  close_sockets();
  1914. +  if (!cli_open_sockets(0)) return(False);
  1915. +
  1916. +  return(cli_send_login(inbuf,outbuf,True,True));
  1917. +}
  1918. +
  1919. +/* error code stuff - put together by Merik Karman
  1920. +   merik@blackadder.dsh.oz.au */
  1921. +
  1922. +typedef struct
  1923. +{
  1924. +  char *name;
  1925. +  int code;
  1926. +  char *message;
  1927. +} err_code_struct;
  1928. +
  1929. +/* Dos Error Messages */
  1930. +err_code_struct dos_msgs[] = {
  1931. +  {"ERRbadfunc",1,"Invalid function."},
  1932. +  {"ERRbadfile",2,"File not found."},
  1933. +  {"ERRbadpath",3,"Directory invalid."},
  1934. +  {"ERRnofids",4,"No file descriptors available"},
  1935. +  {"ERRnoaccess",5,"Access denied."},
  1936. +  {"ERRbadfid",6,"Invalid file handle."},
  1937. +  {"ERRbadmcb",7,"Memory control blocks destroyed."},
  1938. +  {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
  1939. +  {"ERRbadmem",9,"Invalid memory block address."},
  1940. +  {"ERRbadenv",10,"Invalid environment."},
  1941. +  {"ERRbadformat",11,"Invalid format."},
  1942. +  {"ERRbadaccess",12,"Invalid open mode."},
  1943. +  {"ERRbaddata",13,"Invalid data."},
  1944. +  {"ERR",14,"reserved."},
  1945. +  {"ERRbaddrive",15,"Invalid drive specified."},
  1946. +  {"ERRremcd",16,"A Delete Directory request attempted  to  remove  the  server's  current directory."},
  1947. +  {"ERRdiffdevice",17,"Not same device."},
  1948. +  {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
  1949. +  {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing  FIDs  on the file."},
  1950. +  {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an  invalid mode,  or an Unlock requested attempted to remove a lock held by another process."},
  1951. +  {"ERRfilexists",80,"The file named in a Create Directory, Make  New  File  or  Link  request already exists."},
  1952. +  {"ERRbadpipe",230,"Pipe invalid."},
  1953. +  {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
  1954. +  {"ERRpipeclosing",232,"Pipe close in progress."},
  1955. +  {"ERRnotconnected",233,"No process on other end of pipe."},
  1956. +  {"ERRmoredata",234,"There is more data to be returned."},
  1957. +  {NULL,-1,NULL}};
  1958. +
  1959. +/* Server Error Messages */
  1960. +err_code_struct server_msgs[] = {
  1961. +  {"ERRerror",1,"Non-specific error code."},
  1962. +  {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
  1963. +  {"ERRbadtype",3,"reserved."},
  1964. +  {"ERRaccess",4,"The requester does not have  the  necessary  access  rights  within  the specified  context for the requested function. The context is defined by the TID or the UID."},
  1965. +  {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
  1966. +  {"ERRinvnetname",6,"Invalid network name in tree connect."},
  1967. +  {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or  non-printer request made to printer connection."},
  1968. +  {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
  1969. +  {"ERRqtoobig",50,"Print queue full -- no space."},
  1970. +  {"ERRqeof",51,"EOF on print queue dump."},
  1971. +  {"ERRinvpfid",52,"Invalid print file FID."},
  1972. +  {"ERRsmbcmd",64,"The server did not recognize the command received."},
  1973. +  {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
  1974. +  {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid  combination of values."},
  1975. +  {"ERRreserved",68,"reserved."},
  1976. +  {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination.  The server cannot set the requested attribute."},
  1977. +  {"ERRreserved",70,"reserved."},
  1978. +  {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
  1979. +  {"ERRpaused",81,"Server is paused."},
  1980. +  {"ERRmsgoff",82,"Not receiving messages."},
  1981. +  {"ERRnoroom",83,"No room to buffer message."},
  1982. +  {"ERRrmuns",87,"Too many remote user names."},
  1983. +  {"ERRtimeout",88,"Operation timed out."},
  1984. +  {"ERRnoresource",89,"No resources currently available for request."},
  1985. +  {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
  1986. +  {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
  1987. +  {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
  1988. +  {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
  1989. +  {"ERRcontmpx",252,"Continue in MPX mode."},
  1990. +  {"ERRreserved",253,"reserved."},
  1991. +  {"ERRreserved",254,"reserved."},
  1992. +  {"ERRnosupport",0xFFFF,"Function not supported."},
  1993. +  {NULL,-1,NULL}};
  1994. +
  1995. +/* Hard Error Messages */
  1996. +err_code_struct hard_msgs[] = {
  1997. +  {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
  1998. +  {"ERRbadunit",20,"Unknown unit."},
  1999. +  {"ERRnotready",21,"Drive not ready."},
  2000. +  {"ERRbadcmd",22,"Unknown command."},
  2001. +  {"ERRdata",23,"Data error (CRC)."},
  2002. +  {"ERRbadreq",24,"Bad request structure length."},
  2003. +  {"ERRseek",25 ,"Seek error."},
  2004. +  {"ERRbadmedia",26,"Unknown media type."},
  2005. +  {"ERRbadsector",27,"Sector not found."},
  2006. +  {"ERRnopaper",28,"Printer out of paper."},
  2007. +  {"ERRwrite",29,"Write fault."},
  2008. +  {"ERRread",30,"Read fault."},
  2009. +  {"ERRgeneral",31,"General failure."},
  2010. +  {"ERRbadshare",32,"A open conflicts with an existing open."},
  2011. +  {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
  2012. +  {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
  2013. +  {"ERRFCBUnavail",35,"No FCBs are available to process request."},
  2014. +  {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
  2015. +  {NULL,-1,NULL}};
  2016. +
  2017. +
  2018. +struct
  2019. +{
  2020. +  int code;
  2021. +  char *class;
  2022. +  err_code_struct *err_msgs;
  2023. +} err_classes[] = { 
  2024. +  {0,"SUCCESS",NULL},
  2025. +  {0x01,"ERRDOS",dos_msgs},
  2026. +  {0x02,"ERRSRV",server_msgs},
  2027. +  {0x03,"ERRHRD",hard_msgs},
  2028. +  {0x04,"ERRXOS",NULL},
  2029. +  {0xE1,"ERRRMX1",NULL},
  2030. +  {0xE2,"ERRRMX2",NULL},
  2031. +  {0xE3,"ERRRMX3",NULL},
  2032. +  {0xFF,"ERRCMD",NULL},
  2033. +  {-1,NULL,NULL}};
  2034. +
  2035. +
  2036. +/****************************************************************************
  2037. +return a SMB error string from a SMB buffer
  2038. +****************************************************************************/
  2039. +char *smb_errstr(char *inbuf)
  2040. +{
  2041. +  static pstring ret;
  2042. +  int class = CVAL(inbuf,smb_rcls);
  2043. +  int num = SVAL(inbuf,smb_err);
  2044. +  int i,j;
  2045. +
  2046. +  for (i=0;err_classes[i].class;i++)
  2047. +    if (err_classes[i].code == class)
  2048. +      {
  2049. +    if (err_classes[i].err_msgs)
  2050. +      {
  2051. +        err_code_struct *err = err_classes[i].err_msgs;
  2052. +        for (j=0;err[j].name;j++)
  2053. +          if (num == err[j].code)
  2054. +        {
  2055. +          if (DEBUGLEVEL > 0)
  2056. +            sprintf(ret,"%s - %s (%s)",err_classes[i].class,
  2057. +                err[j].name,err[j].message);
  2058. +          else
  2059. +            sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
  2060. +          return ret;
  2061. +        }
  2062. +      }
  2063. +
  2064. +    sprintf(ret,"%s - %d",err_classes[i].class,num);
  2065. +    return ret;
  2066. +      }
  2067. +  
  2068. +  sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);
  2069. +  return(ret);
  2070. +}
  2071. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/clitar.c samba-1.9.16alpha5/source/clitar.c
  2072. --- samba-1.9.16alpha4/source/clitar.c    Sat Jun  1 01:15:11 1996
  2073. +++ samba-1.9.16alpha5/source/clitar.c    Wed Jun  5 01:16:26 1996
  2074. @@ -23,12 +23,6 @@
  2075.  #include "includes.h"
  2076.  #include "clitar.h"
  2077.  
  2078. -extern void setup_pkt(char *outbuf);
  2079. -extern BOOL reopen_connection(char *inbuf,char *outbuf);
  2080. -extern void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
  2081. -
  2082. -int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
  2083. -
  2084.  extern BOOL recurse;
  2085.  
  2086.  #define SEPARATORS " \t\n\r"
  2087. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/cvs.log samba-1.9.16alpha5/source/cvs.log
  2088. --- samba-1.9.16alpha4/source/cvs.log    Sat Jun  1 01:16:32 1996
  2089. +++ samba-1.9.16alpha5/source/cvs.log    Wed Jun  5 01:20:27 1996
  2090. @@ -965,3 +965,135 @@
  2091.  Log Message:
  2092.  preparing for release of 1.9.16alpha4
  2093.  
  2094. +
  2095. +****************************************
  2096. +Date:    Sunday June 2, 1996 @ 1:25
  2097. +Author:    tridge
  2098. +
  2099. +Update of /data/cvs/samba/source
  2100. +In directory arvidsjaur:/var/tmp/cvs-serv20106
  2101. +
  2102. +Modified Files:
  2103. +    Makefile includes.h ipc.c loadparm.c loadparm.h server.c smb.h 
  2104. +    smbrun.c util.c 
  2105. +Added Files:
  2106. +    uid.c 
  2107. +Log Message:
  2108. +- moved the uid handling to uid.c
  2109. +- added setfsuid() support (for Linux)
  2110. +- started adding some of Lukes changes, just the loadparm and ipc ones
  2111. +so far
  2112. +
  2113. +
  2114. +
  2115. +
  2116. +
  2117. +****************************************
  2118. +Date:    Tuesday June 4, 1996 @ 16:41
  2119. +Author:    tridge
  2120. +
  2121. +Update of /data/cvs/samba/source
  2122. +In directory arvidsjaur:/data/tridge/samba/source
  2123. +
  2124. +Modified Files:
  2125. +    Makefile charcnv.c client.c clitar.c getsmbpass.c includes.h 
  2126. +    kanji.c loadparm.c loadparm.h local.h md4.c nameserv.c 
  2127. +    nameserv.h nmblib.c nmblookup.c nmbsync.c params.c params.h 
  2128. +    password.c reply.c server.c smb.h smbencrypt.c smbpass.c 
  2129. +    smbpasswd.c smbrun.c status.c testparm.c trans2.c ufc.c uid.c 
  2130. +    util.c vt_mode.c 
  2131. +Added Files:
  2132. +    clientutil.c localnet.h mkproto.awk nameannounce.c namedb.c 
  2133. +    nameelect.c namequery.c nameresp.c namework.c nmbd.c proto.h 
  2134. +Removed Files:
  2135. +    sockspy.c 
  2136. +Log Message:
  2137. +a huge pile of changes :-)
  2138. +
  2139. +The biggest thing is the integration of Lukes new nmbd. Its still
  2140. +largely untested, so we will really need some feedback
  2141. +
  2142. +I've also added auto prototype generation and cleaned up a lot of
  2143. +minor things as a result
  2144. +
  2145. +
  2146. +
  2147. +****************************************
  2148. +Date:    Tuesday June 4, 1996 @ 16:53
  2149. +Author:    tridge
  2150. +
  2151. +Update of /data/cvs/samba/source
  2152. +In directory arvidsjaur:/data/tridge/samba/source
  2153. +
  2154. +Modified Files:
  2155. +    mkproto.awk namework.c quotas.c 
  2156. +Log Message:
  2157. +add dummy quotas fn
  2158. +fix typo in reply to backup lists
  2159. +
  2160. +
  2161. +
  2162. +****************************************
  2163. +Date:    Wednesday June 5, 1996 @ 1:12
  2164. +Author:    tridge
  2165. +
  2166. +Update of /data/cvs/samba/docs
  2167. +In directory arvidsjaur:/var/tmp/cvs-serv30528
  2168. +
  2169. +Modified Files:
  2170. +    smb.conf.5 
  2171. +Log Message:
  2172. +Did more integration of Lukes code ready for the first release.
  2173. +
  2174. +I've now got WINS registration working, and refresh working. Its
  2175. +looking pretty good so far, but needs lots of testing.
  2176. +
  2177. +
  2178. +
  2179. +
  2180. +****************************************
  2181. +Date:    Wednesday June 5, 1996 @ 1:14
  2182. +Author:    tridge
  2183. +
  2184. +Update of /data/cvs/samba/source
  2185. +In directory arvidsjaur:/var/tmp/cvs-serv30555
  2186. +
  2187. +Modified Files:
  2188. +    client.c loadparm.c loadparm.h nameannounce.c namedb.c 
  2189. +    nameelect.c nameresp.c nameserv.c nameserv.h namework.c nmbd.c 
  2190. +    nmblib.c nmbsync.c util.c 
  2191. +Log Message:
  2192. +Did more integration of Lukes code ready for the first release.
  2193. +
  2194. +I've now got WINS registration working, and refresh working. Its
  2195. +looking pretty good so far, but needs lots of testing.
  2196. +
  2197. +
  2198. +
  2199. +
  2200. +****************************************
  2201. +Date:    Wednesday June 5, 1996 @ 1:19
  2202. +Author:    samba-bugs
  2203. +
  2204. +Update of /data/cvs/samba/docs
  2205. +In directory arvidsjaur:/samba/samba-bugs/samba/docs
  2206. +
  2207. +Modified Files:
  2208. +    Support.txt 
  2209. +Log Message:
  2210. +updated the entry for Phillip Hands
  2211. +
  2212. +
  2213. +
  2214. +****************************************
  2215. +Date:    Wednesday June 5, 1996 @ 1:19
  2216. +Author:    samba-bu
  2217. +
  2218. +Update of /data/cvs/samba/source
  2219. +In directory arvidsjaur:/samba/samba-bugs/samba/source
  2220. +
  2221. +Modified Files:
  2222. +    version.h 
  2223. +Log Message:
  2224. +preparing for release of 1.9.16alpha5
  2225. +
  2226. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/getsmbpass.c samba-1.9.16alpha5/source/getsmbpass.c
  2227. --- samba-1.9.16alpha4/source/getsmbpass.c    Sat May  4 17:50:23 1996
  2228. +++ samba-1.9.16alpha5/source/getsmbpass.c    Wed Jun  5 01:16:26 1996
  2229. @@ -40,12 +40,12 @@
  2230.  #define TCSANOW 0
  2231.  #endif
  2232.  
  2233. -int tcgetattr(int fd, struct termio *t)
  2234. + int tcgetattr(int fd, struct termio *t)
  2235.  {
  2236.      return ioctl(fd, TCGETA, t);
  2237.  }
  2238.  
  2239. -int tcsetattr(int fd, int flags, const struct termio *t)
  2240. + int tcsetattr(int fd, int flags, const struct termio *t)
  2241.  {
  2242.      if(flags & TCSAFLUSH)
  2243.          ioctl(fd, TCFLSH, TCIOFLUSH);
  2244. @@ -71,12 +71,12 @@
  2245.  #define TCSANOW 0
  2246.  #endif
  2247.  
  2248. -int tcgetattr(int fd, struct sgttyb *t)
  2249. + int tcgetattr(int fd, struct sgttyb *t)
  2250.  {
  2251.      return ioctl(fd, TIOCGETP, (char *)t);
  2252.  }
  2253.  
  2254. -int tcsetattr(int fd, int flags, const struct sgttyb *t)
  2255. + int tcsetattr(int fd, int flags, const struct sgttyb *t)
  2256.  {
  2257.      return ioctl(fd, TIOCSETP, (char *)t);
  2258.  }
  2259. @@ -92,8 +92,7 @@
  2260.  #endif /* BSD_TERMIO */
  2261.  #endif /* SYSV_TERMIO */
  2262.  
  2263. -char *
  2264. -getsmbpass(char *prompt)     
  2265. +char *getsmbpass(char *prompt)    
  2266.  {
  2267.    FILE *in, *out;
  2268.    int echo_off;
  2269. @@ -162,5 +161,5 @@
  2270.  
  2271.  #else
  2272.  
  2273. -void getsmbpasswd_dummy() {;}
  2274. + void getsmbpasswd_dummy() {;}
  2275.  #endif
  2276. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/includes.h samba-1.9.16alpha5/source/includes.h
  2277. --- samba-1.9.16alpha4/source/includes.h    Sat Jun  1 01:15:11 1996
  2278. +++ samba-1.9.16alpha5/source/includes.h    Wed Jun  5 01:16:26 1996
  2279. @@ -223,6 +223,7 @@
  2280.  #define USE_SETSID
  2281.  #define HAVE_BZERO
  2282.  #define HAVE_MEMMOVE
  2283. +#define USE_SETFS
  2284.  #ifdef SHADOW_PWD
  2285.  #ifndef crypt
  2286.  #define crypt pw_encrypt
  2287. @@ -982,6 +983,8 @@
  2288.  
  2289.  #include "version.h"
  2290.  #include "smb.h"
  2291. +#include "nameserv.h"
  2292. +#include "proto.h"
  2293.  #include "byteorder.h"
  2294.  #ifdef SMB_PASSWD
  2295.  #include "smbpass.h"
  2296. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/ipc.c samba-1.9.16alpha5/source/ipc.c
  2297. --- samba-1.9.16alpha4/source/ipc.c    Sat Jun  1 01:15:12 1996
  2298. +++ samba-1.9.16alpha5/source/ipc.c    Mon Jun  3 10:41:13 1996
  2299. @@ -751,44 +751,64 @@
  2300.    filter out unwanted server info 
  2301.    ******************************************************************/
  2302.  static BOOL filter_server_info(struct srv_info_struct *server, 
  2303. -                   char *domain)
  2304. +                   BOOL domains,
  2305. +                   char *domain, uint32 request)
  2306.  {
  2307. -  if (*domain)
  2308. -    return(strequal(domain, server->domain));
  2309. -  
  2310. -  return (True); /* be indiscriminate: get all servers! */
  2311. -}
  2312. -
  2313. -/*******************************************************************
  2314. -  find server in the files saved by nmbd. Return True if we find it.
  2315. -  ******************************************************************/
  2316. -static BOOL find_server(struct srv_info_struct *servers, int num_servers,
  2317. -         char *domain, char *name)
  2318. -{
  2319. -  int count;
  2320. -
  2321. -  if (!servers || num_servers == 0) return (False);
  2322. -
  2323. -  for (count = 0; count < num_servers; count++)    {
  2324. -    struct srv_info_struct *s;
  2325. -
  2326. -    s = &servers[count];
  2327. -
  2328. -    if (strequal(name, s->name)) {
  2329. -      StrnCpy(domain, s->domain, sizeof(pstring)-1);
  2330. -      return (True);
  2331. +  if (*domain == 0)
  2332. +    {
  2333. +      if (strequal(lp_workgroup(), server->domain)) {
  2334. +    return True;
  2335. +      }
  2336. +      else if (domains)
  2337. +    {
  2338. +      DEBUG(4,("primary domain:reject %8x %s %s\n",request,server->name,server->domain));
  2339. +      return False;
  2340. +    }
  2341. +      else if ((request & SV_TYPE_DOMAIN_ENUM) &&
  2342. +           (server->type & SV_TYPE_DOMAIN_ENUM))
  2343. +    {
  2344. +      DEBUG(4,("rej:DOM %8x: %s %s\n",server->type,server->name,server->domain));
  2345. +      return False;
  2346. +    }
  2347. +      
  2348. +      return True;
  2349. +    }
  2350. +  else
  2351. +    {
  2352. +      if (strequal(domain, server->domain))
  2353. +    {
  2354. +      /*
  2355. +        if (request     == SV_TYPE_LOCAL_LIST_ONLY &&
  2356. +        !(server->type & SV_TYPE_LOCAL_LIST_ONLY))
  2357. +        {
  2358. +        DEBUG(4,("rej:LOC %8x: ok %s %s\n",request,server->name,server->domain));
  2359. +        return False;
  2360. +        }
  2361. +        */
  2362. +      if ((request == (SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM)) &&
  2363. +                !(server->type&SV_TYPE_DOMAIN_ENUM))
  2364. +        {
  2365. +          DEBUG(4,("rej:LOCDOM %8x: ok %s %s\n",request,server->name,server->domain));
  2366. +          return False;
  2367. +        }
  2368. +      
  2369. +      return True;
  2370. +    }
  2371. +      else if (!domains)
  2372. +    {
  2373. +      DEBUG(4,("domain:%s %s %s\n",domain,server->name,server->domain));
  2374. +      return False;
  2375. +    }
  2376. +      return True;
  2377.      }
  2378. -  }
  2379. -  return (False);
  2380.  }
  2381.  
  2382. -
  2383.  /*******************************************************************
  2384.    get server info lists from the files saved by nmbd. Return the
  2385.    number of entries
  2386.    ******************************************************************/
  2387.  static int get_server_info(uint32 servertype, 
  2388. -               struct srv_info_struct **servers)
  2389. +               struct srv_info_struct **servers, BOOL domains, char *domain)
  2390.  {
  2391.    FILE *f;
  2392.    pstring fname;
  2393. @@ -807,18 +827,23 @@
  2394.      DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
  2395.      return(0);
  2396.    }
  2397. +
  2398. +  /* request for everything is code for request all servers */
  2399.    if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM;
  2400.  
  2401. +  DEBUG(4, ("Servertype search: %8x domains:%s\n", servertype,BOOLSTR(domains)));
  2402. +
  2403.    while (!feof(f))
  2404.    {
  2405.      fstring stype;
  2406.      struct srv_info_struct *s;
  2407.      char *ptr = line;
  2408. +    BOOL ok = True;
  2409.      *ptr = 0;
  2410.  
  2411.      fgets(line,sizeof(line)-1,f);
  2412.      if (!*line) continue;
  2413. -
  2414. +    
  2415.      if (count == alloced) {
  2416.        alloced += 10;
  2417.        (*servers) = (struct srv_info_struct *)
  2418. @@ -827,32 +852,52 @@
  2419.        bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count));
  2420.      }
  2421.      s = &(*servers)[count];
  2422. -
  2423. -    s->server_added = True;
  2424. -
  2425. +    
  2426.      if (!next_token(&ptr,s->name   , NULL)) continue;
  2427.      if (!next_token(&ptr,stype     , NULL)) continue;
  2428.      if (!next_token(&ptr,s->comment, NULL)) continue;
  2429.      if (!next_token(&ptr,s->domain , NULL)) {
  2430. -      /* this allows us to cop with an old nmbd */
  2431. +      /* this allows us to cope with an old nmbd */
  2432.        strcpy(s->domain,my_workgroup()); 
  2433.      }
  2434. -
  2435. -    if (sscanf(stype,"%X",&s->type) != 1) continue;
  2436. -
  2437. +    
  2438. +    if (sscanf(stype,"%X",&s->type) != 1) { DEBUG(4,("r:host file ")); ok = False; }
  2439. +    
  2440.      /* doesn't match up: don't want it */
  2441. -    if (!(servertype & s->type)) continue;
  2442. -
  2443. -    /* server entry is a domain, we haven't asked for domains: don't want it */
  2444. -    if ((s->type&SV_TYPE_DOMAIN_ENUM) && !(servertype&SV_TYPE_DOMAIN_ENUM))
  2445. -      continue;
  2446. -
  2447. -    DEBUG(4,("Server %20s %8x %25s %15s\n",
  2448. -         s->name, stype, s->comment, s->domain));
  2449. -
  2450. -    count++;
  2451. +    if (!(servertype & s->type)) { DEBUG(4,("r:serv type ")); ok = False; }
  2452. +    
  2453. +    if ((servertype == ~SV_TYPE_DOMAIN_ENUM) &&
  2454. +    (s->type & SV_TYPE_DOMAIN_ENUM))
  2455. +      {
  2456. +    DEBUG(4,("s:all x dom  "));
  2457. +    ok = False;
  2458. +      }
  2459. +    
  2460. +    if (domains && !(domain && *domain && strequal(domain, s->domain)))
  2461. +      {
  2462. +    if (!(s->type & SV_TYPE_DOMAIN_ENUM))
  2463. +      {
  2464. +        DEBUG(4,("r:dom enum  "));
  2465. +        ok = False;
  2466. +      }
  2467. +      }
  2468. +    
  2469. +    if (ok)
  2470. +      {
  2471. +        DEBUG(4,("**SV** %20s %8x %25s %15s\n",
  2472. +         s->name, s->type, s->comment, s->domain));
  2473. +    
  2474. +    s->type |= SV_TYPE_LOCAL_LIST_ONLY;
  2475. +        s->server_added = True;
  2476. +        count++;
  2477. +      }
  2478. +    else
  2479. +      {
  2480. +    DEBUG(4,("%20s %8x %25s %15s\n",
  2481. +         s->name, s->type, s->comment, s->domain));
  2482. +      }
  2483.    }
  2484. -
  2485. +  
  2486.    fclose(f);
  2487.    return(count);
  2488.  }
  2489. @@ -957,8 +1002,14 @@
  2490.    int counted=0,total=0;
  2491.    int i;
  2492.    fstring domain;
  2493. -  BOOL domain_request = (servertype & SV_TYPE_DOMAIN_ENUM) &&
  2494. -                       !(servertype == SV_TYPE_ALL);
  2495. +  BOOL domains;
  2496. +  BOOL domain_request;
  2497. +  BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY;
  2498. +
  2499. +  /*if (servertype == SV_TYPE_ALL) servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);*/
  2500. +  if (servertype == SV_TYPE_ALL) servertype &= ~SV_TYPE_DOMAIN_ENUM;
  2501. +
  2502. +  domain_request = servertype & SV_TYPE_DOMAIN_ENUM;
  2503.  
  2504.    domain[0] = 0;
  2505.    p += 8;
  2506. @@ -966,49 +1017,46 @@
  2507.    if (!prefix_ok(str1,"WrLehD")) return False;
  2508.    if (!check_server_info(uLevel,str2)) return False;
  2509.    
  2510. -  DEBUG(4, ("server request level: %s\n", str2));
  2511. +  DEBUG(4, ("server request level: %s %8x ", str2, servertype));
  2512. +  DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
  2513. +  DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
  2514.  
  2515.    if (strcmp(str1, "WrLehDO") == 0)
  2516.    {
  2517. -    /* asking for servers. we will have to work out which workgroup was
  2518. -       requested, as we maintain lists for multiple workgroups */
  2519. +    domains = False;
  2520.    }
  2521.    else if (strcmp(str1, "WrLehDz") == 0)
  2522.    {
  2523. -    /* asking for a specific workgroup */
  2524. +    domains = True;
  2525.      StrnCpy(domain, p, sizeof(fstring)-1);
  2526.    }
  2527.  
  2528.    if (lp_browse_list())
  2529.    {
  2530. -    total = get_server_info(servertype,&servers);
  2531. -  }
  2532. -
  2533. -  if (!domain[0] && !domain_request) {
  2534. -    extern fstring remote_machine;
  2535. -    /* must be a server request with an assumed domain. find a domain */
  2536. -    
  2537. -    if (find_server(servers, total, domain, remote_machine)) {
  2538. -      DEBUG(4, ("No domain specified: using %s for %s\n",
  2539. -        domain, remote_machine));
  2540. -    } else {
  2541. -      /* default to soemthing sensible */
  2542. -      strcpy(domain,my_workgroup());
  2543. -    }
  2544. +    total = get_server_info(servertype,&servers,domains,domain);
  2545.    }
  2546.  
  2547.    data_len = fixed_len = string_len = 0;
  2548.  
  2549. -  for (i=0;i<total;i++)
  2550. -    if (filter_server_info(&servers[i],domain)) {
  2551. -      data_len += fill_srv_info(&servers[i],uLevel,0,&f_len,0,&s_len,0);
  2552. -      if (data_len <= buf_len)
  2553. -    {
  2554. -      counted++;
  2555. -      fixed_len += f_len;
  2556. -      string_len += s_len;
  2557. -    }
  2558. +  {
  2559. +    for (i=0;i<total;i++)
  2560. +    {
  2561. +      struct srv_info_struct *s = &servers[i];
  2562. +      if (filter_server_info(s,domains,domain,local_request|domain_request))
  2563. +      {
  2564. +        data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
  2565. +          DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
  2566. +                s->name, s->type, s->comment, s->domain));
  2567. +
  2568. +        if (data_len <= buf_len)
  2569. +        {
  2570. +          counted++;
  2571. +          fixed_len += f_len;
  2572. +          string_len += s_len;
  2573. +        }
  2574. +      }
  2575.      }
  2576. +  }
  2577.  
  2578.    *rdata_len = fixed_len + string_len;
  2579.    *rdata = REALLOC(*rdata,*rdata_len);
  2580. @@ -1021,10 +1069,15 @@
  2581.  
  2582.    {
  2583.      int count2 = counted;
  2584. -    for (i = 0; i < total && count2;i++) {
  2585. -      if (filter_server_info(&servers[i],domain)) {
  2586. -    fill_srv_info(&servers[i],uLevel,&p,&f_len,&p2,&s_len,*rdata);
  2587. -    count2--;
  2588. +    for (i = 0; i < total && count2;i++)
  2589. +    {
  2590. +      struct srv_info_struct *s = &servers[i];
  2591. +      if (filter_server_info(s,domains,domain,local_request|domain_request))
  2592. +      {
  2593. +        fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
  2594. +          DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
  2595. +                s->name, s->type, s->comment, s->domain));
  2596. +        count2--;
  2597.        }
  2598.      }
  2599.    }
  2600. @@ -1657,7 +1710,7 @@
  2601.  
  2602.        strcpy(comment,lp_serverstring());
  2603.  
  2604. -      if ((count=get_server_info(SV_TYPE_ALL,&servers))>0) {
  2605. +      if ((count=get_server_info(SV_TYPE_ALL,&servers,False,NULL))>0) {
  2606.      for (i=0;i<count;i++)
  2607.        if (strequal(servers[i].name,local_machine)) {
  2608.          servertype = servers[i].type;
  2609. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/kanji.c samba-1.9.16alpha5/source/kanji.c
  2610. --- samba-1.9.16alpha4/source/kanji.c    Sat May  4 17:50:23 1996
  2611. +++ samba-1.9.16alpha5/source/kanji.c    Wed Jun  5 01:16:27 1996
  2612. @@ -796,8 +796,7 @@
  2613.  /*
  2614.   * Interpret coding system.
  2615.   */
  2616. -int 
  2617. -interpret_coding_system (char *str, int def)
  2618. +int interpret_coding_system(char *str, int def)
  2619.  {
  2620.      int codes = def;
  2621.      
  2622. @@ -890,6 +889,6 @@
  2623.      return setup_string_function (codes);
  2624.  }
  2625.  #else 
  2626. -int kanji_dummy_procedure(void)
  2627. + int kanji_dummy_procedure(void)
  2628.  {return 0;}
  2629.  #endif /* KANJI */
  2630. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/loadparm.c samba-1.9.16alpha5/source/loadparm.c
  2631. --- samba-1.9.16alpha4/source/loadparm.c    Sat Jun  1 01:15:12 1996
  2632. +++ samba-1.9.16alpha5/source/loadparm.c    Wed Jun  5 01:16:27 1996
  2633. @@ -58,7 +58,6 @@
  2634.  extern int DEBUGLEVEL;
  2635.  extern int ReadSize;
  2636.  extern pstring user_socket_options;
  2637. -extern pstring smbrun_path;
  2638.  
  2639.  #ifndef GLOBAL_NAME
  2640.  #define GLOBAL_NAME "global"
  2641. @@ -132,6 +131,8 @@
  2642.     char *szUsernameMap;
  2643.     char *szCharacterSet;
  2644.     char *szLogonScript;
  2645. +   char *szSmbrun;
  2646. +   char *szWINSserver;
  2647.     int max_log_size;
  2648.     int mangled_stack;
  2649.     int max_xmit;
  2650. @@ -147,6 +148,8 @@
  2651.     int syslog;
  2652.     int os_level;
  2653.     int max_ttl;
  2654. +   BOOL bWINSsupport;
  2655. +   BOOL bWINSproxy;
  2656.     BOOL bPreferredMaster;
  2657.     BOOL bDomainMaster;
  2658.     BOOL bDomainLogons;
  2659. @@ -161,7 +164,6 @@
  2660.     BOOL bReadbmpx;
  2661.     BOOL bSyslogOnly;
  2662.     BOOL bBrowseList;
  2663. -   BOOL bProxyNameResolution;
  2664.  } global;
  2665.  
  2666.  static global Globals;
  2667. @@ -368,7 +370,7 @@
  2668.    {"strip dot",        P_BOOL,    P_GLOBAL, &Globals.bStripDot,         NULL},
  2669.    {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL},
  2670.    {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL},
  2671. -  {"smbrun",           P_GSTRING, P_GLOBAL, smbrun_path,                NULL},
  2672. +  {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL},
  2673.    {"log file",         P_STRING,  P_GLOBAL, &Globals.szLogFile,         NULL},
  2674.    {"config file",      P_STRING,  P_GLOBAL, &Globals.szConfigFile,      NULL},
  2675.    {"smb passwd file",  P_STRING,  P_GLOBAL, &Globals.szSMBPasswdFile,   NULL},
  2676. @@ -411,12 +413,14 @@
  2677.  #endif /* KANJI */
  2678.    {"os level",         P_INTEGER, P_GLOBAL, &Globals.os_level,          NULL},
  2679.    {"max ttl",          P_INTEGER, P_GLOBAL, &Globals.max_ttl,           NULL},
  2680. +  {"wins support",     P_BOOL,    P_GLOBAL, &Globals.bWINSsupport,      NULL},
  2681. +  {"wins proxy",       P_BOOL,    P_GLOBAL, &Globals.bWINSproxy,        NULL},
  2682. +  {"wins server",      P_STRING,  P_GLOBAL, &Globals.szWINSserver,      NULL},
  2683.    {"preferred master", P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL},
  2684.    {"prefered master",  P_BOOL,    P_GLOBAL, &Globals.bPreferredMaster,  NULL},
  2685.    {"domain master",    P_BOOL,    P_GLOBAL, &Globals.bDomainMaster,     NULL},
  2686.    {"domain logons",    P_BOOL,    P_GLOBAL, &Globals.bDomainLogons,     NULL},
  2687.    {"browse list",      P_BOOL,    P_GLOBAL, &Globals.bBrowseList,       NULL},
  2688. -  {"proxy name resolution",P_BOOL,P_GLOBAL,&Globals.bProxyNameResolution,NULL},
  2689.  
  2690.    {"-valid",           P_BOOL,    P_LOCAL,  &sDefault.valid,            NULL},
  2691.    {"comment",          P_STRING,  P_LOCAL,  &sDefault.comment,          NULL},
  2692. @@ -543,6 +547,7 @@
  2693.    string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
  2694.    string_set(&Globals.szLockDir, LOCKDIR);
  2695.    string_set(&Globals.szRootdir, "/");
  2696. +  string_set(&Globals.szSmbrun, SMBRUN);
  2697.    sprintf(s,"Samba %s",VERSION);
  2698.    string_set(&Globals.szServerString,s);
  2699.    Globals.bLoadPrinters = True;
  2700. @@ -573,7 +578,8 @@
  2701.    Globals.bDomainMaster = False;
  2702.    Globals.bDomainLogons = False;
  2703.    Globals.bBrowseList = True;
  2704. -  Globals.bProxyNameResolution = True;
  2705. +  Globals.bWINSsupport = True;
  2706. +  Globals.bWINSproxy = False;
  2707.  
  2708.  #ifdef KANJI
  2709.    coding_system = interpret_coding_system (KANJI, SJIS_CODE);
  2710. @@ -677,6 +683,7 @@
  2711.   int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
  2712.  
  2713.  FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
  2714. +FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
  2715.  FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
  2716.  FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
  2717.  FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
  2718. @@ -696,7 +703,10 @@
  2719.  FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
  2720.  FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet) 
  2721.  FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) 
  2722. +FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
  2723.  
  2724. +FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
  2725. +FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
  2726.  FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
  2727.  FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
  2728.  FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
  2729. @@ -712,7 +722,6 @@
  2730.  FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
  2731.  FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
  2732.  FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
  2733. -FN_GLOBAL_BOOL(lp_proxy_name_resolution,&Globals.bProxyNameResolution)
  2734.  
  2735.  FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
  2736.  FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
  2737. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/loadparm.h samba-1.9.16alpha5/source/loadparm.h
  2738. --- samba-1.9.16alpha4/source/loadparm.h    Sat Jun  1 01:15:12 1996
  2739. +++ samba-1.9.16alpha5/source/loadparm.h    Wed Jun  5 01:16:27 1996
  2740. @@ -43,6 +43,7 @@
  2741.  extern char *lp_printcapname(void);
  2742.  extern char *lp_lockdir(void);
  2743.  extern char *lp_logfile(void);
  2744. +extern char *lp_smbrun(void);
  2745.  extern char *lp_configfile(void);
  2746.  extern char *lp_smb_passwd_file(void);
  2747.  extern char *lp_rootdir(void);
  2748. @@ -55,6 +56,7 @@
  2749.  extern char *lp_username_map(void);
  2750.  extern char *lp_hosts_equiv(void);
  2751.  extern char *lp_logon_script(void);
  2752. +extern char *lp_wins_server(void);
  2753.  extern char *lp_magicscript(int iService);
  2754.  extern char *lp_magicoutput(int iService);
  2755.  extern char *lp_mangled_map(int iService);
  2756. @@ -65,6 +67,8 @@
  2757.  extern int  lp_maxxmit(void);
  2758.  extern int  lp_maxmux(void);
  2759.  extern int  lp_mangledstack(void);
  2760. +extern BOOL lp_wins_support(void);
  2761. +extern BOOL lp_wins_proxy(void);
  2762.  extern BOOL lp_preferred_master(void);
  2763.  extern BOOL lp_domain_master(void);
  2764.  extern BOOL lp_domain_logons(void);
  2765. @@ -79,7 +83,6 @@
  2766.  extern BOOL lp_encrypted_passwords(void);
  2767.  extern BOOL lp_syslog_only(void);
  2768.  extern BOOL lp_browse_list(void);
  2769. -extern BOOL lp_proxy_name_resolution(void);
  2770.  extern int  lp_numservices(void);
  2771.  extern int  lp_keepalive(void);
  2772.  extern int  lp_passwordlevel(void);
  2773. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/local.h samba-1.9.16alpha5/source/local.h
  2774. --- samba-1.9.16alpha4/source/local.h    Sat Jun  1 01:15:12 1996
  2775. +++ samba-1.9.16alpha5/source/local.h    Wed Jun  5 01:16:27 1996
  2776. @@ -130,7 +130,7 @@
  2777.  #define IDLE_CLOSED_TIMEOUT (60)
  2778.  #define DPTR_IDLE_TIMEOUT (120)
  2779.  #define SMBD_SELECT_LOOP (10)
  2780. -#define NMBD_SELECT_LOOP (10)
  2781. +#define NMBD_SELECT_LOOP (2)
  2782.  #define BROWSE_INTERVAL (60)
  2783.  #define REGISTRATION_INTERVAL (10*60)
  2784.  #define NMBD_INETD_TIMEOUT (120)
  2785. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/localnet.h samba-1.9.16alpha5/source/localnet.h
  2786. --- samba-1.9.16alpha4/source/localnet.h    Thu Jan  1 10:00:00 1970
  2787. +++ samba-1.9.16alpha5/source/localnet.h    Tue Jun  4 16:41:12 1996
  2788. @@ -0,0 +1,6 @@
  2789. +extern struct in_addr myip;
  2790. +extern struct in_addr bcast_ip;
  2791. +extern struct in_addr Netmask;
  2792. +
  2793. +extern int ClientNMB;
  2794. +extern int ClientDGRAM;
  2795. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/md4.c samba-1.9.16alpha5/source/md4.c
  2796. --- samba-1.9.16alpha4/source/md4.c    Sat May  4 17:50:24 1996
  2797. +++ samba-1.9.16alpha5/source/md4.c    Wed Jun  5 01:16:27 1996
  2798. @@ -295,5 +295,5 @@
  2799.   ** End of md4.c
  2800.   */
  2801.  #else
  2802. -void md4_dummy() {;}
  2803. + void md4_dummy() {;}
  2804.  #endif
  2805. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/mkproto.awk samba-1.9.16alpha5/source/mkproto.awk
  2806. --- samba-1.9.16alpha4/source/mkproto.awk    Thu Jan  1 10:00:00 1970
  2807. +++ samba-1.9.16alpha5/source/mkproto.awk    Tue Jun  4 16:53:22 1996
  2808. @@ -0,0 +1,39 @@
  2809. +# generate prototypes for Samba C code
  2810. +# tridge, June 1996
  2811. +
  2812. +BEGIN {
  2813. +  inheader=0;
  2814. +}
  2815. +
  2816. +{
  2817. +  if (inheader) {
  2818. +    if (match($0,"[)][ \t]*$")) {
  2819. +      inheader = 0;
  2820. +      printf "%s;\n",$0;
  2821. +    } else {
  2822. +      printf "%s\n",$0;
  2823. +    }
  2824. +    next;
  2825. +  }
  2826. +}
  2827. +
  2828. +/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
  2829. +  next;
  2830. +}
  2831. +
  2832. +!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
  2833. +  next;
  2834. +}
  2835. +
  2836. +
  2837. +/[(].*[)][ \t]*$/ {
  2838. +    printf "%s;\n",$0;
  2839. +    next;
  2840. +}
  2841. +
  2842. +/[(]/ {
  2843. +  inheader=1;
  2844. +  printf "%s\n",$0;
  2845. +  next;
  2846. +}
  2847. +
  2848. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nameannounce.c samba-1.9.16alpha5/source/nameannounce.c
  2849. --- samba-1.9.16alpha4/source/nameannounce.c    Thu Jan  1 10:00:00 1970
  2850. +++ samba-1.9.16alpha5/source/nameannounce.c    Wed Jun  5 01:14:22 1996
  2851. @@ -0,0 +1,442 @@
  2852. +/* 
  2853. +   Unix SMB/Netbios implementation.
  2854. +   Version 1.9.
  2855. +   NBT netbios routines and daemon - version 2
  2856. +   Copyright (C) Andrew Tridgell 1994-1995
  2857. +   
  2858. +   This program is free software; you can redistribute it and/or modify
  2859. +   it under the terms of the GNU General Public License as published by
  2860. +   the Free Software Foundation; either version 2 of the License, or
  2861. +   (at your option) any later version.
  2862. +   
  2863. +   This program is distributed in the hope that it will be useful,
  2864. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  2865. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2866. +   GNU General Public License for more details.
  2867. +   
  2868. +   You should have received a copy of the GNU General Public License
  2869. +   along with this program; if not, write to the Free Software
  2870. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  2871. +   
  2872. +   Revision History:
  2873. +
  2874. +   14 jan 96: lkcl@pires.co.uk
  2875. +   added multiple workgroup domain master support
  2876. +
  2877. +*/
  2878. +
  2879. +#include "includes.h"
  2880. +#include "loadparm.h"
  2881. +
  2882. +#define TEST_CODE
  2883. +
  2884. +extern int DEBUGLEVEL;
  2885. +extern BOOL CanRecurse;
  2886. +
  2887. +extern struct in_addr myip;
  2888. +extern struct in_addr bcast_ip;
  2889. +extern struct in_addr Netmask;
  2890. +extern struct in_addr ipzero;
  2891. +
  2892. +extern pstring myname;
  2893. +
  2894. +extern int ClientDGRAM;
  2895. +extern int ClientNMB;
  2896. +
  2897. +/* this is our domain/workgroup/server database */
  2898. +extern struct domain_record *domainlist;
  2899. +
  2900. +/* machine comment for host announcements */
  2901. +extern  pstring ServerComment;
  2902. +
  2903. +extern int  updatecount;
  2904. +extern int  workgroup_count;
  2905. +
  2906. +/* what server type are we currently */
  2907. +
  2908. +#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  2909. +#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
  2910. +#define AM_DOMCTL(work) (work->ServerType & SV_TYPE_DOMAIN_CTRL)
  2911. +
  2912. +#define MSBROWSE "\001\002__MSBROWSE__\002"
  2913. +#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  2914. +
  2915. +/****************************************************************************
  2916. +  send a announce request to the local net
  2917. +  **************************************************************************/
  2918. +void announce_request(struct work_record *work, struct in_addr ip)
  2919. +{
  2920. +  pstring outbuf;
  2921. +  char *p;
  2922. +
  2923. +  if (!work) return;
  2924. +
  2925. +  work->needannounce = True;
  2926. +
  2927. +  DEBUG(2,("Sending announce request to %s for workgroup %s\n",
  2928. +       inet_ntoa(ip),work->work_group));
  2929. +
  2930. +  bzero(outbuf,sizeof(outbuf));
  2931. +  p = outbuf;
  2932. +  CVAL(p,0) = 2; /* announce request */
  2933. +  p++;
  2934. +
  2935. +  CVAL(p,0) = work->token; /* flags?? XXXX probably a token*/
  2936. +  p++;
  2937. +  StrnCpy(p,myname,16);
  2938. +  strupper(p);
  2939. +  p = skip_string(p,1);
  2940. +  
  2941. +  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  2942. +              myname,work->work_group,0x20,0x0,ip,myip);
  2943. +}
  2944. +
  2945. +
  2946. +/****************************************************************************
  2947. +  request an announcement
  2948. +  **************************************************************************/
  2949. +void do_announce_request(char *info, char *to_name, int announce_type, int from,
  2950. +             int to, struct in_addr dest_ip)
  2951. +{
  2952. +  pstring outbuf;
  2953. +  char *p;
  2954. +  
  2955. +  bzero(outbuf,sizeof(outbuf));
  2956. +  p = outbuf;
  2957. +  CVAL(p,0) = announce_type; /* announce request */
  2958. +  p++;
  2959. +  
  2960. +  DEBUG(2,("Sending announce type %d: info %s to %s - server %s(%x)\n",
  2961. +       announce_type, info, inet_ntoa(dest_ip),to_name,to));
  2962. +  
  2963. +  StrnCpy(p,info,16);
  2964. +  strupper(p);
  2965. +  p = skip_string(p,1);
  2966. +  
  2967. +  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  2968. +              myname,to_name,from,to,dest_ip,myip);
  2969. +}
  2970. +
  2971. +/****************************************************************************
  2972. +  construct a host announcement unicast
  2973. +  **************************************************************************/
  2974. +void announce_backup(void)
  2975. +{
  2976. +    static time_t lastrun = 0;
  2977. +    time_t t = time(NULL);
  2978. +    pstring outbuf;
  2979. +    char *p;
  2980. +    struct domain_record *d1;
  2981. +    int tok;
  2982. +
  2983. +    if (!lastrun) lastrun = t;
  2984. +    if (t < lastrun + 1*60) return;
  2985. +    lastrun = t;
  2986. +
  2987. +    for (tok = 0; tok <= workgroup_count; tok++)
  2988. +    {
  2989. +        for (d1 = domainlist; d1; d1 = d1->next)
  2990. +        {
  2991. +            struct work_record *work;
  2992. +            struct domain_record *d;
  2993. +
  2994. +            /* search for unique workgroup: only the name matters */
  2995. +            for (work = d1->workgrouplist;
  2996. +                 work && (tok != work->token);
  2997. +                 work = work->next);
  2998. +
  2999. +            if (work)
  3000. +            {
  3001. +                /* found one: announce it across all domains */
  3002. +                for (d = domainlist; d; d = d->next)
  3003. +                {
  3004. +                    DEBUG(2,("Sending announce backup %s workgroup %s(%d)\n",
  3005. +                         inet_ntoa(d->bcast_ip),work->work_group,
  3006. +                         work->token));
  3007. +
  3008. +                    bzero(outbuf,sizeof(outbuf));
  3009. +                    p = outbuf;
  3010. +                    CVAL(p,0) = 9; /* backup list response */
  3011. +                    p++;
  3012. +
  3013. +                    CVAL(p,0) = 1; /* count? */
  3014. +                    SIVAL(p,1,work->token); /* workgroup unique key index */
  3015. +                    p += 5;
  3016. +                    p++;
  3017. +
  3018. +                    if (AM_DOMCTL(work))
  3019. +                    {
  3020. +                        send_mailslot_reply(BROWSE_MAILSLOT,
  3021. +                               ClientDGRAM,outbuf,
  3022. +                               PTR_DIFF(p,outbuf),
  3023. +                               myname, work->work_group,
  3024. +                               0x0,0x1b,d->bcast_ip,myip);
  3025. +                    }
  3026. +                    else if (AM_MASTER(work))
  3027. +                    {
  3028. +                        send_mailslot_reply(BROWSE_MAILSLOT,
  3029. +                               ClientDGRAM,outbuf,
  3030. +                               PTR_DIFF(p,outbuf),
  3031. +                               myname, work->work_group,
  3032. +                               0x0,0x1d,d->bcast_ip,myip);
  3033. +                    }
  3034. +                }
  3035. +            }
  3036. +        }
  3037. +    }
  3038. +}
  3039. +
  3040. +
  3041. +/****************************************************************************
  3042. +  construct a host announcement unicast
  3043. +  **************************************************************************/
  3044. +void announce_host(void)
  3045. +{
  3046. +  time_t t = time(NULL);
  3047. +  pstring outbuf;
  3048. +  char *p;
  3049. +  char *namep;
  3050. +  char *stypep;
  3051. +  char *commentp;
  3052. +  pstring comment;
  3053. +  char *my_name;
  3054. +  struct domain_record *d;
  3055. +
  3056. +  StrnCpy(comment, *ServerComment ? ServerComment : "NoComment", 43);
  3057. +
  3058. +  my_name = *myname ? myname : "NoName";
  3059. +
  3060. +  for (d = domainlist; d; d = d->next)
  3061. +    {
  3062. +      struct work_record *work;
  3063. +      
  3064. +      if (!ip_equal(bcast_ip,d->bcast_ip))
  3065. +    continue;
  3066. +
  3067. +      for (work = d->workgrouplist; work; work = work->next)
  3068. +    {
  3069. +      uint32 stype = work->ServerType;
  3070. +      struct server_record *s;
  3071. +      BOOL announce = False;
  3072. +      
  3073. +      if (work->needannounce) {
  3074. +        /* drop back to a max 3 minute announce - this is to prevent a
  3075. +           single lost packet from stuffing things up for too long */
  3076. +        work->announce_interval = MIN(work->announce_interval,3*60);
  3077. +        work->lastannounce_time = t - (work->announce_interval+1);
  3078. +      }
  3079. +      
  3080. +      /* announce every minute at first then progress to every 12 mins */
  3081. +      if (work->lastannounce_time && 
  3082. +          (t - work->lastannounce_time) < work->announce_interval)
  3083. +        continue;
  3084. +      
  3085. +      if (work->announce_interval < 12*60) 
  3086. +        work->announce_interval += 60;
  3087. +      
  3088. +      work->lastannounce_time = t;
  3089. +
  3090. +      DEBUG(2,("Sending announcement to subnet %s for workgroup %s\n",
  3091. +           inet_ntoa(d->bcast_ip),work->work_group));
  3092. +
  3093. +      if (!ip_equal(bcast_ip,d->bcast_ip)) {
  3094. +        stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
  3095. +               SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
  3096. +               SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
  3097. +      }
  3098. +
  3099. +      for (s = work->serverlist; s; s = s->next) {
  3100. +        if (strequal(myname, s->serv.name)) { 
  3101. +          announce = True; 
  3102. +          break; 
  3103. +        }
  3104. +      }
  3105. +      
  3106. +      if (announce)
  3107. +        {
  3108. +          bzero(outbuf,sizeof(outbuf));
  3109. +          p = outbuf+1;
  3110. +          
  3111. +          CVAL(p,0) = updatecount;
  3112. +          SIVAL(p,1,work->announce_interval*1000); /* ms - despite the spec */
  3113. +          namep = p+5;
  3114. +          StrnCpy(namep,my_name,16);
  3115. +          strupper(namep);
  3116. +          CVAL(p,21) = 2; /* major version */
  3117. +          CVAL(p,22) = 2; /* minor version */
  3118. +          stypep = p+23;
  3119. +          SIVAL(p,23,stype);
  3120. +          SSVAL(p,27,0xaa55); /* browse signature */
  3121. +          SSVAL(p,29,1); /* browse version */
  3122. +          commentp = p+31;
  3123. +          strcpy(commentp,comment);
  3124. +          p = p+31;
  3125. +          p = skip_string(p,1);
  3126. +          
  3127. +          if (ip_equal(bcast_ip,d->bcast_ip))
  3128. +        {
  3129. +          if (AM_MASTER(work))
  3130. +            {
  3131. +              SIVAL(stypep,0,work->ServerType);
  3132. +              
  3133. +              CVAL(outbuf,0) = 15; /* local member announce */
  3134. +              
  3135. +              send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  3136. +                      PTR_DIFF(p,outbuf),
  3137. +                      my_name,work->work_group,0,
  3138. +                      0x1e,d->bcast_ip,myip);
  3139. +              
  3140. +              CVAL(outbuf,0) = 12; /* domain announce */
  3141. +              
  3142. +              StrnCpy(namep,work->work_group,15);
  3143. +              strupper(namep);
  3144. +              StrnCpy(commentp,myname,15);
  3145. +              strupper(commentp);
  3146. +              
  3147. +              SIVAL(stypep,0,(unsigned)0x80000000);
  3148. +              p = commentp + strlen(commentp) + 1;
  3149. +              
  3150. +              send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  3151. +                      PTR_DIFF(p,outbuf),
  3152. +                      my_name,MSBROWSE,0,0x01,d->bcast_ip,myip);
  3153. +            }
  3154. +          else
  3155. +            {
  3156. +              CVAL(outbuf,0) = 1; /* host announce */
  3157. +              
  3158. +              send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
  3159. +                      PTR_DIFF(p,outbuf),
  3160. +                      my_name,work->work_group,0,0x1d,d->bcast_ip,myip);
  3161. +            }
  3162. +        }
  3163. +        }
  3164. +      
  3165. +      if (work->needannounce)
  3166. +        {
  3167. +          work->needannounce = False;
  3168. +          break;
  3169. +          /* sorry: can't do too many announces. do some more later */
  3170. +        }
  3171. +    }
  3172. +    }
  3173. +}
  3174. +
  3175. +
  3176. +/****************************************************************************
  3177. +  announce myself as a master to all other primary domain conrollers.
  3178. +
  3179. +  BIG NOTE: this code will remain untested until some kind soul that has access
  3180. +  to a couple of windows NT advanced servers runs this version of nmbd for at
  3181. +  least 15 minutes.
  3182. +  
  3183. +  this actually gets done in search_and_sync_workgroups() via the
  3184. +  MASTER_SERVER_CHECK command, if there is a response from the
  3185. +  name query initiated here.  see response_name_query()
  3186. +  **************************************************************************/
  3187. +void announce_master(void)
  3188. +{
  3189. +  struct domain_record *d;
  3190. +  static time_t last=0;
  3191. +  time_t t = time(NULL);
  3192. +  BOOL am_master = False; /* are we a master of some sort? :-) */
  3193. +
  3194. +#ifdef TEST_CODE
  3195. +  if (last && (t-last < 2*60)) return;
  3196. +#else
  3197. +  if (last && (t-last < 15*60)) return; 
  3198. +#endif
  3199. +
  3200. +  last = t;
  3201. +
  3202. +  for (d = domainlist; d; d = d->next)
  3203. +    {
  3204. +      struct work_record *work;
  3205. +      for (work = d->workgrouplist; work; work = work->next)
  3206. +    {
  3207. +      if (AM_MASTER(work))
  3208. +        {
  3209. +          am_master = True;
  3210. +        }
  3211. +    }
  3212. +    }
  3213. +  
  3214. +  if (!am_master) return; /* only proceed if we are a master browser */
  3215. +  
  3216. +  for (d = domainlist; d; d = d->next)
  3217. +    {
  3218. +      struct work_record *work;
  3219. +      for (work = d->workgrouplist; work; work = work->next)
  3220. +    {
  3221. +      struct server_record *s;
  3222. +      for (s = work->serverlist; s; s = s->next)
  3223. +        {
  3224. +          if (strequal(s->serv.name, myname)) continue;
  3225. +          
  3226. +          /* all PDCs (which should also be master browsers) */
  3227. +          if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
  3228. +        {
  3229. +          /* check the existence of a pdc for this workgroup, and if
  3230. +             one exists at the specified ip, sync with it and announce
  3231. +             ourselves as a master browser to it */
  3232. +          
  3233. +          if (!*lp_domain_controller() ||
  3234. +              !strequal(lp_domain_controller(), s->serv.name))
  3235. +            {
  3236. +              if (!lp_wins_support() && *lp_wins_server())
  3237. +            {
  3238. +              struct in_addr ip;
  3239. +              ip = ipzero;
  3240. +              
  3241. +              queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
  3242. +                         MASTER_SERVER_CHECK,
  3243. +                         work->work_group,0x1b,0,
  3244. +                         False, False, ip);
  3245. +            }
  3246. +              else
  3247. +            {
  3248. +              struct domain_record *d2;
  3249. +              for (d2 = domainlist; d2; d2 = d2->next)
  3250. +                {
  3251. +                  queue_netbios_packet(ClientNMB,NMB_QUERY,
  3252. +                           MASTER_SERVER_CHECK,
  3253. +                           work->work_group,0x1b,0,
  3254. +                           True, False, d2->bcast_ip);
  3255. +                }
  3256. +            }
  3257. +            }
  3258. +        }
  3259. +        }
  3260. +      
  3261. +      /* now do primary domain controller - the one that's not
  3262. +         necessarily in our browse lists, although it ought to be
  3263. +         this pdc is the one that we get TOLD about through smb.conf.
  3264. +         basically, if it's on a subnet that we know about, it may end
  3265. +         up in our browse lists (which is why it's explicitly excluded
  3266. +         in the code above) */
  3267. +      
  3268. +      if (*lp_domain_controller())
  3269. +        {
  3270. +          struct in_addr ip;
  3271. +          BOOL bcast = False;
  3272. +          
  3273. +          ip = *interpret_addr2(lp_domain_controller());
  3274. +          
  3275. +          if (zero_ip(ip))
  3276. +        {
  3277. +          ip = bcast_ip;
  3278. +          bcast = True;
  3279. +        }
  3280. +
  3281. +          DEBUG(2, ("Searching for PDC %s at %s\n",
  3282. +            lp_domain_controller(), inet_ntoa(ip)));
  3283. +          
  3284. +          /* check the existence of a pdc for this workgroup, and if
  3285. +         one exists at the specified ip, sync with it and announce
  3286. +         ourselves as a master browser to it */
  3287. +          queue_netbios_pkt_wins(ClientNMB, NMB_QUERY,MASTER_SERVER_CHECK,
  3288. +                     work->work_group,0x1b, 0,
  3289. +                     bcast, False, ip);
  3290. +        }
  3291. +    }
  3292. +    }
  3293. +}
  3294. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/namedb.c samba-1.9.16alpha5/source/namedb.c
  3295. --- samba-1.9.16alpha4/source/namedb.c    Thu Jan  1 10:00:00 1970
  3296. +++ samba-1.9.16alpha5/source/namedb.c    Wed Jun  5 01:14:22 1996
  3297. @@ -0,0 +1,709 @@
  3298. +/* 
  3299. +   Unix SMB/Netbios implementation.
  3300. +   Version 1.9.
  3301. +   NBT netbios routines and daemon - version 2
  3302. +   Copyright (C) Andrew Tridgell 1994-1995
  3303. +   
  3304. +   This program is free software; you can redistribute it and/or modify
  3305. +   it under the terms of the GNU General Public License as published by
  3306. +   the Free Software Foundation; either version 2 of the License, or
  3307. +   (at your option) any later version.
  3308. +   
  3309. +   This program is distributed in the hope that it will be useful,
  3310. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  3311. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  3312. +   GNU General Public License for more details.
  3313. +   
  3314. +   You should have received a copy of the GNU General Public License
  3315. +   along with this program; if not, write to the Free Software
  3316. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  3317. +   
  3318. +   Revision History:
  3319. +
  3320. +   14 jan 96: lkcl@pires.co.uk
  3321. +   added multiple workgroup domain master support
  3322. +
  3323. +*/
  3324. +
  3325. +#include "includes.h"
  3326. +#include "smb.h"
  3327. +#include "loadparm.h"
  3328. +#include "localnet.h"
  3329. +
  3330. +extern int DEBUGLEVEL;
  3331. +
  3332. +extern time_t StartupTime;
  3333. +extern pstring myname;
  3334. +extern pstring scope;
  3335. +extern struct in_addr bcast_ip;
  3336. +
  3337. +/* this is our browse master/backup cache database */
  3338. +struct browse_cache_record *browserlist = NULL;
  3339. +
  3340. +/* this is our domain/workgroup/server database */
  3341. +struct domain_record *domainlist = NULL;
  3342. +
  3343. +static BOOL updatedlists = True;
  3344. +int  updatecount=0;
  3345. +
  3346. +int workgroup_count = 0; /* unique index key: one for each workgroup */
  3347. +
  3348. +/* what server type are we currently */
  3349. +
  3350. +#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
  3351. +            SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
  3352. +            SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
  3353. +
  3354. +/* here are my election parameters */
  3355. +#define MSBROWSE "\001\002__MSBROWSE__\002"
  3356. +
  3357. +
  3358. +/****************************************************************************
  3359. +  add a workgroup into the domain list
  3360. +  **************************************************************************/
  3361. +static void add_workgroup(struct work_record *work, struct domain_record *d)
  3362. +{
  3363. +  struct work_record *w2;
  3364. +
  3365. +  if (!work || !d) return;
  3366. +
  3367. +  if (!d->workgrouplist)
  3368. +    {
  3369. +      d->workgrouplist = work;
  3370. +      work->prev = NULL;
  3371. +      work->next = NULL;
  3372. +      return;
  3373. +    }
  3374. +  
  3375. +  for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
  3376. +  
  3377. +  w2->next = work;
  3378. +  work->next = NULL;
  3379. +  work->prev = w2;
  3380. +}
  3381. +
  3382. +
  3383. +/****************************************************************************
  3384. +  create a blank workgroup 
  3385. +  **************************************************************************/
  3386. +static struct work_record *make_workgroup(char *name)
  3387. +{
  3388. +  struct work_record *work;
  3389. +  struct domain_record *d;
  3390. +  int t = -1;
  3391. +  
  3392. +  if (!name || !name[0]) return NULL;
  3393. +  
  3394. +  work = (struct work_record *)malloc(sizeof(*work));
  3395. +  if (!work) return(NULL);
  3396. +  
  3397. +  StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
  3398. +  work->serverlist = NULL;
  3399. +  
  3400. +  work->ServerType = DFLT_SERVER_TYPE;
  3401. +  work->RunningElection = False;
  3402. +  work->ElectionCount = 0;
  3403. +  work->needelection = False;
  3404. +  work->needannounce = True;
  3405. +  
  3406. +  /* make sure all token representations of workgroups are unique */
  3407. +  
  3408. +  for (d = domainlist; d && t == -1; d = d->next)
  3409. +    {
  3410. +      struct work_record *w;
  3411. +      for (w = d->workgrouplist; w && t == -1; w = w->next)
  3412. +    {
  3413. +      if (strequal(w->work_group, work->work_group)) t = w->token;
  3414. +    }
  3415. +    }
  3416. +  
  3417. +  if (t == -1)
  3418. +    {
  3419. +      work->token = ++workgroup_count;
  3420. +    }
  3421. +  else
  3422. +    {
  3423. +      work->token = t;
  3424. +    }
  3425. +  
  3426. +  
  3427. +  /* WfWg  uses 01040b01 */
  3428. +  /* Win95 uses 01041501 */
  3429. +  /* NTAS  uses ???????? */
  3430. +  work->ElectionCriterion  = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8); 
  3431. +  work->ElectionCriterion |= (lp_os_level() << 24);
  3432. +  if (lp_domain_master()) {
  3433. +    work->ElectionCriterion |= 0x80;
  3434. +  }
  3435. +  
  3436. +  return work;
  3437. +}
  3438. +
  3439. +
  3440. +/*******************************************************************
  3441. +  expire old servers in the serverlist
  3442. +  time of -1 indicates everybody dies
  3443. +  ******************************************************************/
  3444. +static void remove_old_servers(struct work_record *work, time_t t)
  3445. +{
  3446. +  struct server_record *s;
  3447. +  struct server_record *nexts;
  3448. +  
  3449. +  /* expire old entries in the serverlist */
  3450. +  for (s = work->serverlist; s; s = nexts)
  3451. +    {
  3452. +      if (t == -1 || (s->death_time && s->death_time < t))
  3453. +    {
  3454. +      DEBUG(3,("Removing dead server %s\n",s->serv.name));
  3455. +      updatedlists = True;
  3456. +      nexts = s->next;
  3457. +      
  3458. +      if (s->prev) s->prev->next = s->next;
  3459. +      if (s->next) s->next->prev = s->prev;
  3460. +      
  3461. +      if (work->serverlist == s) 
  3462. +        work->serverlist = s->next; 
  3463. +
  3464. +      free(s);
  3465. +    }
  3466. +      else
  3467. +    {
  3468. +      nexts = s->next;
  3469. +    }
  3470. +    }
  3471. +}
  3472. +
  3473. +
  3474. +/*******************************************************************
  3475. +  remove workgroups
  3476. +  ******************************************************************/
  3477. +struct work_record *remove_workgroup(struct domain_record *d, struct work_record *work)
  3478. +{
  3479. +  struct work_record *ret_work = NULL;
  3480. +  
  3481. +  if (!d || !work) return NULL;
  3482. +  
  3483. +  DEBUG(3,("Removing old workgroup %s\n", work->work_group));
  3484. +  
  3485. +  remove_old_servers(work, -1);
  3486. +  
  3487. +  ret_work = work->next;
  3488. +  
  3489. +  if (work->prev) work->prev->next = work->next;
  3490. +  if (work->next) work->next->prev = work->prev;
  3491. +  
  3492. +  if (d->workgrouplist == work) d->workgrouplist = work->next; 
  3493. +  
  3494. +  free(work);
  3495. +  
  3496. +  return ret_work;
  3497. +}
  3498. +
  3499. +
  3500. +/****************************************************************************
  3501. +  add a domain into the list
  3502. +  **************************************************************************/
  3503. +static void add_domain(struct domain_record *d)
  3504. +{
  3505. +  struct domain_record *d2;
  3506. +
  3507. +  if (!domainlist)
  3508. +  {
  3509. +    domainlist = d;
  3510. +    d->prev = NULL;
  3511. +    d->next = NULL;
  3512. +    return;
  3513. +  }
  3514. +
  3515. +  for (d2 = domainlist; d2->next; d2 = d2->next);
  3516. +
  3517. +  d2->next = d;
  3518. +  d->next = NULL;
  3519. +  d->prev = d2;
  3520. +}
  3521. +
  3522. +/***************************************************************************
  3523. +  add a browser into the list
  3524. +  **************************************************************************/
  3525. +static void add_browse_cache(struct browse_cache_record *b)
  3526. +{
  3527. +  struct browse_cache_record *b2;
  3528. +
  3529. +  if (!browserlist)
  3530. +    {
  3531. +      browserlist = b;
  3532. +      b->prev = NULL;
  3533. +      b->next = NULL;
  3534. +      return;
  3535. +    }
  3536. +  
  3537. +  for (b2 = browserlist; b2->next; b2 = b2->next) ;
  3538. +  
  3539. +  b2->next = b;
  3540. +  b->next = NULL;
  3541. +  b->prev = b2;
  3542. +}
  3543. +
  3544. +
  3545. +/***************************************************************************
  3546. +  add a server into the list
  3547. +  **************************************************************************/
  3548. +static void add_server(struct work_record *work,struct server_record *s)
  3549. +{
  3550. +  struct server_record *s2;
  3551. +
  3552. +  if (!work->serverlist) {
  3553. +    work->serverlist = s;
  3554. +    s->prev = NULL;
  3555. +    s->next = NULL;
  3556. +    return;
  3557. +  }
  3558. +
  3559. +  for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
  3560. +
  3561. +  s2->next = s;
  3562. +  s->next = NULL;
  3563. +  s->prev = s2;
  3564. +}
  3565. +
  3566. +
  3567. +/*******************************************************************
  3568. +  remove old browse entries
  3569. +  ******************************************************************/
  3570. +void expire_browse_cache(time_t t)
  3571. +{
  3572. +  struct browse_cache_record *b;
  3573. +  struct browse_cache_record *nextb;
  3574. +  
  3575. +  /* expire old entries in the serverlist */
  3576. +  for (b = browserlist; b; b = nextb)
  3577. +    {
  3578. +      if (b->synced && b->sync_time < t)
  3579. +    {
  3580. +      DEBUG(3,("Removing dead cached browser %s\n",b->name));
  3581. +      nextb = b->next;
  3582. +      
  3583. +      if (b->prev) b->prev->next = b->next;
  3584. +      if (b->next) b->next->prev = b->prev;
  3585. +      
  3586. +      if (browserlist == b) browserlist = b->next; 
  3587. +      
  3588. +      free(b);
  3589. +    }
  3590. +      else
  3591. +    {
  3592. +      nextb = b->next;
  3593. +    }
  3594. +    }
  3595. +}
  3596. +
  3597. +
  3598. +/****************************************************************************
  3599. +  find a workgroup in the workgrouplist 
  3600. +  only create it if the domain allows it, or the parameter 'add' insists
  3601. +  that it get created/added anyway. this allows us to force entries in
  3602. +  lmhosts file to be added.
  3603. +  **************************************************************************/
  3604. +struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add)
  3605. +{
  3606. +  struct work_record *ret, *work;
  3607. +  
  3608. +  if (!d) return NULL;
  3609. +  
  3610. +  DEBUG(4, ("workgroup search for %s: ", name));
  3611. +  
  3612. +  if (strequal(name, "*"))
  3613. +    {
  3614. +      DEBUG(2,("add any workgroups: initiating browser search on %s\n",
  3615. +           inet_ntoa(d->bcast_ip)));
  3616. +      queue_netbios_pkt_wins(ClientNMB,NMB_QUERY, FIND_MASTER,
  3617. +                 MSBROWSE,0x1,0,
  3618. +                 True,False, d->bcast_ip);
  3619. +      return NULL;
  3620. +    }
  3621. +  
  3622. +  for (ret = d->workgrouplist; ret; ret = ret->next)
  3623. +    {
  3624. +      if (!strcmp(ret->work_group,name))
  3625. +    {
  3626. +      DEBUG(4, ("found\n"));
  3627. +      return(ret);
  3628. +    }
  3629. +    }
  3630. +  
  3631. +  DEBUG(4, ("not found: creating\n"));
  3632. +  
  3633. +  if ((work = make_workgroup(name)))
  3634. +    {
  3635. +      if (lp_preferred_master() &&
  3636. +      strequal(lp_workgroup(), name) &&
  3637. +      ip_equal(d->bcast_ip, bcast_ip))
  3638. +    {
  3639. +      DEBUG(3, ("preferred master startup for %s\n", work->work_group));
  3640. +      work->needelection = True;
  3641. +      work->ElectionCriterion |= (1<<3);
  3642. +    }
  3643. +      if (!ip_equal(bcast_ip, d->bcast_ip))
  3644. +    {
  3645. +      work->needelection = False;
  3646. +    }
  3647. +      add_workgroup(work, d);
  3648. +      return(work);
  3649. +    }
  3650. +  return NULL;
  3651. +}
  3652. +
  3653. +/****************************************************************************
  3654. +  find a domain in the domainlist 
  3655. +  **************************************************************************/
  3656. +struct domain_record *find_domain(struct in_addr source_ip)
  3657. +{   
  3658. +  struct domain_record *d;
  3659. +  
  3660. +  /* search through domain list for broadcast/netmask that matches
  3661. +     the source ip address */
  3662. +  
  3663. +  for (d = domainlist; d; d = d->next)
  3664. +    {
  3665. +      if (same_net(source_ip, d->bcast_ip, d->mask_ip))
  3666. +    {
  3667. +      return(d);
  3668. +    }
  3669. +    }
  3670. +  
  3671. +  return (NULL);
  3672. +}
  3673. +
  3674. +
  3675. +/****************************************************************************
  3676. +  dump a copy of the workgroup/domain database
  3677. +  **************************************************************************/
  3678. +static void dump_workgroups(void)
  3679. +{
  3680. +  struct domain_record *d;
  3681. +  
  3682. +  for (d = domainlist; d; d = d->next)
  3683. +    {
  3684. +      if (d->workgrouplist)
  3685. +    {
  3686. +      struct work_record *work;
  3687. +      
  3688. +      DEBUG(3,("dump domain %15s: ", inet_ntoa(d->bcast_ip)));
  3689. +      DEBUG(3,(" %15s:\n", inet_ntoa(d->bcast_ip)));
  3690. +      
  3691. +      for (work = d->workgrouplist; work; work = work->next)
  3692. +        {
  3693. +          if (work->serverlist)
  3694. +        {
  3695. +          struct server_record *s;
  3696. +          
  3697. +          DEBUG(3,("\t%s(%d)\n", work->work_group, work->token));
  3698. +          for (s = work->serverlist; s; s = s->next)
  3699. +            {
  3700. +              DEBUG(3,("\t\t%s %8x (%s)\n",
  3701. +                   s->serv.name, s->serv.type, s->serv.comment));
  3702. +            }
  3703. +        }
  3704. +        }
  3705. +    }
  3706. +    }
  3707. +}
  3708. +
  3709. +/****************************************************************************
  3710. +  create a domain entry
  3711. +  ****************************************************************************/
  3712. +static struct domain_record *make_domain(struct in_addr ip, struct in_addr mask)
  3713. +{
  3714. +  struct domain_record *d;
  3715. +  d = (struct domain_record *)malloc(sizeof(*d));
  3716. +  
  3717. +  if (!d) return(NULL);
  3718. +  
  3719. +  bzero((char *)d,sizeof(*d));
  3720. +  
  3721. +  DEBUG(4, ("making domain %s ", inet_ntoa(ip)));
  3722. +  DEBUG(4, ("%s\n", inet_ntoa(mask)));
  3723. +  
  3724. +  d->bcast_ip = ip;
  3725. +  d->mask_ip  = mask;
  3726. +  d->workgrouplist = NULL;
  3727. +  
  3728. +  add_domain(d);
  3729. +  
  3730. +  return d;
  3731. +}
  3732. +
  3733. +/****************************************************************************
  3734. +  add a domain entry. creates a workgroup, if necessary, and adds the domain
  3735. +  to the named a workgroup.
  3736. +  ****************************************************************************/
  3737. +struct domain_record *add_domain_entry(struct in_addr source_ip, 
  3738. +                       struct in_addr source_mask,
  3739. +                       char *name, BOOL add)
  3740. +{
  3741. +  struct domain_record *d;
  3742. +  struct in_addr ip;
  3743. +  
  3744. +  ip = *interpret_addr2("255.255.255.255");
  3745. +  
  3746. +  if (zero_ip(source_ip)) source_ip = bcast_ip;
  3747. +  
  3748. +  /* add the domain into our domain database */
  3749. +  if ((d = find_domain(source_ip)) ||
  3750. +      (d = make_domain(source_ip, source_mask)))
  3751. +    {
  3752. +      struct work_record *w = find_workgroupstruct(d, name, add);
  3753. +      
  3754. +      /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
  3755. +     or register with WINS server, if it's our workgroup */
  3756. +      if (strequal(lp_workgroup(), name))
  3757. +    {
  3758. +      extern pstring ServerComment;
  3759. +      add_name_entry(name,0x1e,NB_ACTIVE|NB_GROUP);
  3760. +      add_name_entry(name,0x0 ,NB_ACTIVE|NB_GROUP);
  3761. +      add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
  3762. +    }
  3763. +      
  3764. +      DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(ip)));
  3765. +      return d;
  3766. +    }
  3767. +  return NULL;
  3768. +}
  3769. +
  3770. +/****************************************************************************
  3771. +  add a browser entry
  3772. +  ****************************************************************************/
  3773. +struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
  3774. +                          time_t ttl, struct in_addr ip)
  3775. +{
  3776. +  BOOL newentry=False;
  3777. +  
  3778. +  struct browse_cache_record *b;
  3779. +
  3780. +  /* search for the entry: if it's already in the cache, update that entry */
  3781. +  for (b = browserlist; b; b = b->next)
  3782. +    {
  3783. +      if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
  3784. +    }
  3785. +  
  3786. +  if (b && b->synced)
  3787. +    {
  3788. +      /* entries get left in the cache for a while. this stops sync'ing too
  3789. +     often if the network is large */
  3790. +      DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
  3791. +        b->name, b->group, inet_ntoa(b->ip), b->sync_time));
  3792. +      return NULL;
  3793. +    }
  3794. +  
  3795. +  if (!b)
  3796. +    {
  3797. +      newentry = True;
  3798. +      b = (struct browse_cache_record *)malloc(sizeof(*b));
  3799. +      
  3800. +      if (!b) return(NULL);
  3801. +      
  3802. +      bzero((char *)b,sizeof(*b));
  3803. +    }
  3804. +  
  3805. +  /* update the entry */
  3806. +  ttl = time(NULL)+ttl;
  3807. +  
  3808. +  StrnCpy(b->name ,name,sizeof(b->name )-1);
  3809. +  StrnCpy(b->group,wg  ,sizeof(b->group)-1);
  3810. +  strupper(b->name);
  3811. +  strupper(b->group);
  3812. +  
  3813. +  b->ip     = ip;
  3814. +  b->type   = type;
  3815. +  
  3816. +  if (newentry || ttl < b->sync_time) b->sync_time = ttl;
  3817. +  
  3818. +  if (newentry)
  3819. +    {
  3820. +      b->synced = False;
  3821. +      add_browse_cache(b);
  3822. +      
  3823. +      DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
  3824. +           wg, name, type, inet_ntoa(ip),ttl));
  3825. +    }
  3826. +  else
  3827. +    {
  3828. +      DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
  3829. +           wg, name, type, inet_ntoa(ip),ttl));
  3830. +    }
  3831. +  
  3832. +  return(b);
  3833. +}
  3834. +
  3835. +
  3836. +/****************************************************************************
  3837. +  add a server entry
  3838. +  ****************************************************************************/
  3839. +struct server_record *add_server_entry(struct domain_record *d, 
  3840. +                       struct work_record *work,
  3841. +                       char *name,int servertype, 
  3842. +                       int ttl,char *comment,
  3843. +                       BOOL replace)
  3844. +{
  3845. +  BOOL newentry=False;
  3846. +  struct server_record *s;
  3847. +  
  3848. +  if (name[0] == '*')
  3849. +    {
  3850. +      return (NULL);
  3851. +    }
  3852. +  
  3853. +  for (s = work->serverlist; s; s = s->next)
  3854. +    {
  3855. +      if (strequal(name,s->serv.name)) break;
  3856. +    }
  3857. +  
  3858. +  if (s && !replace)
  3859. +    {
  3860. +      DEBUG(4,("Not replacing %s\n",name));
  3861. +      return(s);
  3862. +    }
  3863. +  
  3864. +  updatedlists=True;
  3865. +  
  3866. +  if (!s)
  3867. +    {
  3868. +      newentry = True;
  3869. +      s = (struct server_record *)malloc(sizeof(*s));
  3870. +      
  3871. +      if (!s) return(NULL);
  3872. +      
  3873. +      bzero((char *)s,sizeof(*s));
  3874. +    }
  3875. +  
  3876. +  if (ip_equal(bcast_ip, d->bcast_ip) &&
  3877. +      strequal(lp_workgroup(),work->work_group))
  3878. +    {
  3879. +      servertype |= SV_TYPE_LOCAL_LIST_ONLY;
  3880. +    }
  3881. +  else
  3882. +    {
  3883. +      servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
  3884. +    }
  3885. +  
  3886. +  /* update the entry */
  3887. +  StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
  3888. +  StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
  3889. +  strupper(s->serv.name);
  3890. +  s->serv.type  = servertype;
  3891. +  s->death_time = ttl?time(NULL)+ttl*3:0;
  3892. +  
  3893. +  /* for a domain entry, the comment field refers to the server name */
  3894. +  
  3895. +  if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
  3896. +  
  3897. +  if (newentry)
  3898. +    {
  3899. +      add_server(work, s);
  3900. +      
  3901. +      DEBUG(3,("Added "));
  3902. +    }
  3903. +  else
  3904. +    {
  3905. +      DEBUG(3,("Updated "));
  3906. +    }
  3907. +  
  3908. +  DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
  3909. +       name,servertype,comment,
  3910. +       work->work_group,inet_ntoa(d->bcast_ip)));
  3911. +  
  3912. +  return(s);
  3913. +}
  3914. +
  3915. +
  3916. +/*******************************************************************
  3917. +  write out browse.dat
  3918. +  ******************************************************************/
  3919. +void write_browse_list(void)
  3920. +{
  3921. +  struct domain_record *d;
  3922. +  
  3923. +  pstring fname,fnamenew;
  3924. +  FILE *f;
  3925. +  
  3926. +  if (!updatedlists) return;
  3927. +  
  3928. +  dump_names();
  3929. +  dump_workgroups();
  3930. +  
  3931. +  updatedlists = False;
  3932. +  updatecount++;
  3933. +  
  3934. +  strcpy(fname,lp_lockdir());
  3935. +  trim_string(fname,NULL,"/");
  3936. +  strcat(fname,"/");
  3937. +  strcat(fname,SERVER_LIST);
  3938. +  strcpy(fnamenew,fname);
  3939. +  strcat(fnamenew,".");
  3940. +  
  3941. +  f = fopen(fnamenew,"w");
  3942. +  
  3943. +  if (!f)
  3944. +    {
  3945. +      DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
  3946. +      return;
  3947. +    }
  3948. +  
  3949. +  for (d = domainlist; d ; d = d->next)
  3950. +    {
  3951. +      struct work_record *work;
  3952. +      for (work = d->workgrouplist; work ; work = work->next)
  3953. +    {
  3954. +      struct server_record *s;
  3955. +      for (s = work->serverlist; s ; s = s->next)
  3956. +        {
  3957. +          fstring tmp;
  3958. +          
  3959. +          /* don't list domains I don't have a master for */
  3960. +          if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) &&
  3961. +          !s->serv.comment[0])
  3962. +        {
  3963. +          continue;
  3964. +        }
  3965. +          
  3966. +          /* output server details, plus what workgroup/domain
  3967. +         they're in. without the domain information, the
  3968. +         combined list of all servers in all workgroups gets
  3969. +         sent to anyone asking about any workgroup! */
  3970. +          
  3971. +          sprintf(tmp, "\"%s\"", s->serv.name);
  3972. +          fprintf(f, "%-25s ", tmp);
  3973. +          fprintf(f, "%08x ", s->serv.type);
  3974. +          sprintf(tmp, "\"%s\"", s->serv.comment);
  3975. +          fprintf(f, "%-30s", tmp);
  3976. +          fprintf(f, "\"%s\"\n", work->work_group);
  3977. +        }
  3978. +    }
  3979. +    }
  3980. +  
  3981. +  fclose(f);
  3982. +  unlink(fname);
  3983. +  chmod(fnamenew,0644);
  3984. +  rename(fnamenew,fname);   
  3985. +  DEBUG(3,("Wrote browse list %s\n",fname));
  3986. +}
  3987. +
  3988. +
  3989. +/*******************************************************************
  3990. +  expire old servers in the serverlist
  3991. +  ******************************************************************/
  3992. +void expire_servers(time_t t)
  3993. +{
  3994. +  struct domain_record *d;
  3995. +  
  3996. +  for (d = domainlist ; d ; d = d->next)
  3997. +    {
  3998. +      struct work_record *work;
  3999. +      
  4000. +      for (work = d->workgrouplist; work; work = work->next)
  4001. +    {
  4002. +      remove_old_servers(work, t);
  4003. +    }
  4004. +    }
  4005. +}
  4006. +
  4007. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nameelect.c samba-1.9.16alpha5/source/nameelect.c
  4008. --- samba-1.9.16alpha4/source/nameelect.c    Thu Jan  1 10:00:00 1970
  4009. +++ samba-1.9.16alpha5/source/nameelect.c    Wed Jun  5 01:14:23 1996
  4010. @@ -0,0 +1,367 @@
  4011. +/* 
  4012. +   Unix SMB/Netbios implementation.
  4013. +   Version 1.9.
  4014. +   NBT netbios routines and daemon - version 2
  4015. +   Copyright (C) Andrew Tridgell 1994-1995
  4016. +   
  4017. +   This program is free software; you can redistribute it and/or modify
  4018. +   it under the terms of the GNU General Public License as published by
  4019. +   the Free Software Foundation; either version 2 of the License, or
  4020. +   (at your option) any later version.
  4021. +   
  4022. +   This program is distributed in the hope that it will be useful,
  4023. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4024. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4025. +   GNU General Public License for more details.
  4026. +   
  4027. +   You should have received a copy of the GNU General Public License
  4028. +   along with this program; if not, write to the Free Software
  4029. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4030. +   
  4031. +   Revision History:
  4032. +
  4033. +   14 jan 96: lkcl@pires.co.uk
  4034. +   added multiple workgroup domain master support
  4035. +
  4036. +*/
  4037. +
  4038. +#include "includes.h"
  4039. +#include "loadparm.h"
  4040. +#include "localnet.h"
  4041. +
  4042. +extern int DEBUGLEVEL;
  4043. +extern pstring scope;
  4044. +
  4045. +extern pstring myname;
  4046. +
  4047. +/* machine comment for host announcements */
  4048. +extern  pstring ServerComment;
  4049. +
  4050. +/* here are my election parameters */
  4051. +
  4052. +extern time_t StartupTime;
  4053. +
  4054. +#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  4055. +
  4056. +#define MSBROWSE "\001\002__MSBROWSE__\002"
  4057. +#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  4058. +
  4059. +extern struct domain_record *domainlist;
  4060. +
  4061. +
  4062. +/*******************************************************************
  4063. +  occasionally check to see if the master browser is around
  4064. +  ******************************************************************/
  4065. +void check_master_browser(void)
  4066. +{
  4067. +    static time_t lastrun=0;
  4068. +    time_t t = time(NULL);
  4069. +    struct domain_record *d;
  4070. +
  4071. +    if (!lastrun) lastrun = t;
  4072. +    if (t < lastrun + 2*60) return;
  4073. +    lastrun = t;
  4074. +
  4075. +    for (d = domainlist; d; d = d->next)
  4076. +    {
  4077. +        struct work_record *work;
  4078. +
  4079. +        for (work = d->workgrouplist; work; work = work->next)
  4080. +        {
  4081. +            /* if we are not the browse master of a workgroup, and we can't
  4082. +               find a browser on the subnet, do something about it. */
  4083. +
  4084. +            if (!AM_MASTER(work))
  4085. +            {
  4086. +                queue_netbios_packet(ClientNMB,NMB_QUERY,CHECK_MASTER,
  4087. +                                 work->work_group,0x1d,0,
  4088. +                                 True,False,d->bcast_ip);
  4089. +            }
  4090. +        }
  4091. +    }
  4092. +}
  4093. +
  4094. +
  4095. +/*******************************************************************
  4096. +  what to do if a master browser DOESN't exist
  4097. +  ******************************************************************/
  4098. +void browser_gone(char *work_name, struct in_addr ip)
  4099. +{
  4100. +    struct domain_record *d = find_domain(ip);
  4101. +    struct work_record *work = find_workgroupstruct(d, work_name, False);
  4102. +
  4103. +    if (!work || !d) return;
  4104. +
  4105. +    DEBUG(2,("Forcing election on %s\n",work->work_group));
  4106. +
  4107. +    if (strequal(work->work_group, lp_workgroup()) &&
  4108. +       ip_equal(bcast_ip, d->bcast_ip))
  4109. +    {
  4110. +        /* we can attempt to become master browser */
  4111. +        work->needelection = True;
  4112. +    }
  4113. +    else
  4114. +    {
  4115. +        DEBUG(2,("no master browser for persistent entry %s %s\n",
  4116. +                  work->work_group, inet_ntoa(d->bcast_ip)));
  4117. +
  4118. +        /* XXXX oh dear. we are going to have problems here. the
  4119. +           entry is a persistent one, there isn't anyone responsible
  4120. +           for this workgroup up and running, yet we can't find it
  4121. +           and we are going to continually have name_queries until
  4122. +           a master browser is found for this workgroup on the
  4123. +           remote subnet.
  4124. +        */
  4125. +    }
  4126. +}
  4127. +/****************************************************************************
  4128. +  send an election packet
  4129. +  **************************************************************************/
  4130. +void send_election(struct domain_record *d, char *group,uint32 criterion,
  4131. +           int timeup,char *name)
  4132. +{
  4133. +  pstring outbuf;
  4134. +  char *p;
  4135. +
  4136. +  if (!d) return;
  4137. +  
  4138. +  DEBUG(2,("Sending election to %s for workgroup %s\n",
  4139. +       inet_ntoa(d->bcast_ip),group));       
  4140. +
  4141. +  bzero(outbuf,sizeof(outbuf));
  4142. +  p = outbuf;
  4143. +  CVAL(p,0) = 8; /* election */
  4144. +  p++;
  4145. +
  4146. +  CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
  4147. +  SIVAL(p,1,criterion);
  4148. +  SIVAL(p,5,timeup*1000); /* ms - despite the spec */
  4149. +  p += 13;
  4150. +  strcpy(p,name);
  4151. +  strupper(p);
  4152. +  p = skip_string(p,1);
  4153. +  
  4154. +  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  4155. +              name,group,0,0x1e,d->bcast_ip,myip);
  4156. +}
  4157. +
  4158. +
  4159. +/*******************************************************************
  4160. +  become the master browser
  4161. +  ******************************************************************/
  4162. +static void become_master(struct domain_record *d, struct work_record *work)
  4163. +{
  4164. +  uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX | 0x00400000;
  4165. +
  4166. +  if (!work) return;
  4167. +  
  4168. +  DEBUG(2,("Becoming master for %s\n",work->work_group));
  4169. +  
  4170. +  work->ServerType |= SV_TYPE_MASTER_BROWSER;
  4171. +  work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
  4172. +  work->ElectionCriterion |= 0x5;
  4173. +  
  4174. +  /* add browse, master and general names to database or register with WINS */
  4175. +  add_name_entry(MSBROWSE        ,0x01,NB_ACTIVE|NB_GROUP);
  4176. +  add_name_entry(work->work_group,0x1d,NB_ACTIVE         );
  4177. +  
  4178. +  if (lp_domain_master())
  4179. +    {
  4180. +      DEBUG(4,("Domain master: adding names...\n"));
  4181. +      
  4182. +      /* add domain master and domain member names or register with WINS */
  4183. +      add_name_entry(work->work_group,0x1b,NB_ACTIVE         );
  4184. +      add_name_entry(work->work_group,0x1c,NB_ACTIVE|NB_GROUP);
  4185. +      
  4186. +      work->ServerType |= SV_TYPE_DOMAIN_MASTER;
  4187. +      
  4188. +      if (lp_domain_logons())
  4189. +    {
  4190. +      work->ServerType |= SV_TYPE_DOMAIN_CTRL;
  4191. +      work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
  4192. +    }
  4193. +    }
  4194. +  
  4195. +  /* update our server status */
  4196. +  add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
  4197. +  add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
  4198. +  
  4199. +  if (ip_equal(bcast_ip, d->bcast_ip))
  4200. +    {
  4201. +      /* ask all servers on our local net to announce to us */
  4202. +      announce_request(work, d->bcast_ip);
  4203. +    }
  4204. +}
  4205. +
  4206. +
  4207. +/*******************************************************************
  4208. +  unbecome the master browser
  4209. +  ******************************************************************/
  4210. +void become_nonmaster(struct domain_record *d, struct work_record *work)
  4211. +{
  4212. +  DEBUG(2,("Becoming non-master for %s\n",work->work_group));
  4213. +  
  4214. +  work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
  4215. +  work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
  4216. +  work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
  4217. +  
  4218. +  work->ElectionCriterion &= ~0x4;
  4219. +  
  4220. +  remove_name_entry(work->work_group,0x1b);
  4221. +  remove_name_entry(work->work_group,0x1c);
  4222. +  remove_name_entry(work->work_group,0x1d);
  4223. +  remove_name_entry(MSBROWSE        ,0x01);
  4224. +}
  4225. +
  4226. +
  4227. +/*******************************************************************
  4228. +  run the election
  4229. +  ******************************************************************/
  4230. +void run_elections(void)
  4231. +{
  4232. +  time_t t = time(NULL);
  4233. +  static time_t lastime = 0;
  4234. +  
  4235. +  struct domain_record *d;
  4236. +  
  4237. +  /* send election packets once a second */
  4238. +  if (lastime && t-lastime <= 0) return;
  4239. +  
  4240. +  lastime = t;
  4241. +  
  4242. +  for (d = domainlist; d; d = d->next)
  4243. +    {
  4244. +      struct work_record *work;
  4245. +      for (work = d->workgrouplist; work; work = work->next)
  4246. +    {
  4247. +      if (work->RunningElection)
  4248. +        {
  4249. +          send_election(d,work->work_group, work->ElectionCriterion,
  4250. +                t-StartupTime,myname);
  4251. +          
  4252. +          if (work->ElectionCount++ >= 4)
  4253. +        {
  4254. +          /* I won! now what :-) */
  4255. +          DEBUG(2,(">>> Won election on %s <<<\n",work->work_group));
  4256. +          
  4257. +          work->RunningElection = False;
  4258. +          become_master(d, work);
  4259. +        }
  4260. +        }
  4261. +    }
  4262. +    }
  4263. +}
  4264. +
  4265. +
  4266. +/*******************************************************************
  4267. +  work out if I win an election
  4268. +  ******************************************************************/
  4269. +static BOOL win_election(struct work_record *work,int version,uint32 criterion,
  4270. +             int timeup,char *name)
  4271. +{  
  4272. +  time_t t = time(NULL);
  4273. +  uint32 mycriterion;
  4274. +  if (version > ELECTION_VERSION) return(False);
  4275. +  if (version < ELECTION_VERSION) return(True);
  4276. +  
  4277. +  mycriterion = work->ElectionCriterion;
  4278. +
  4279. +  if (criterion > mycriterion) return(False);
  4280. +  if (criterion < mycriterion) return(True);
  4281. +
  4282. +  if (timeup > (t - StartupTime)) return(False);
  4283. +  if (timeup < (t - StartupTime)) return(True);
  4284. +
  4285. +  if (strcasecmp(myname,name) > 0) return(False);
  4286. +  
  4287. +  return(True);
  4288. +}
  4289. +
  4290. +
  4291. +/*******************************************************************
  4292. +  process a election packet
  4293. +
  4294. +  An election dynamically decides who will be the master. 
  4295. +  ******************************************************************/
  4296. +void process_election(struct packet_struct *p,char *buf)
  4297. +{
  4298. +  struct dgram_packet *dgram = &p->packet.dgram;
  4299. +  struct in_addr ip = dgram->header.source_ip;
  4300. +  struct domain_record *d = find_domain(ip);
  4301. +  int version = CVAL(buf,0);
  4302. +  uint32 criterion = IVAL(buf,1);
  4303. +  int timeup = IVAL(buf,5)/1000;
  4304. +  char *name = buf+13;
  4305. +  struct work_record *work;
  4306. +
  4307. +  if (!d) return;
  4308. +  
  4309. +  name[15] = 0;  
  4310. +
  4311. +  DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
  4312. +       name,version,criterion,timeup));
  4313. +  
  4314. +  if (same_context(dgram)) return;
  4315. +  
  4316. +  for (work = d->workgrouplist; work; work = work->next)
  4317. +    {
  4318. +      if (listening_name(work, &dgram->dest_name) && 
  4319. +      strequal(work->work_group, lp_workgroup()) &&
  4320. +      ip_equal(d->bcast_ip, bcast_ip))
  4321. +    {
  4322. +      if (win_election(work, version,criterion,timeup,name))
  4323. +        {
  4324. +          if (!work->RunningElection)
  4325. +        {
  4326. +          work->needelection = True;
  4327. +          work->ElectionCount=0;
  4328. +        }
  4329. +        }
  4330. +      else
  4331. +        {
  4332. +          work->needelection = False;
  4333. +          
  4334. +          if (work->RunningElection)
  4335. +        {
  4336. +          work->RunningElection = False;
  4337. +          DEBUG(3,(">>> Lost election on %s <<<\n",work->work_group));
  4338. +          
  4339. +          /* if we are the master then remove our masterly names */
  4340. +          if (AM_MASTER(work))
  4341. +            {
  4342. +              become_nonmaster(d, work);
  4343. +            }
  4344. +        }
  4345. +        }
  4346. +    }
  4347. +    }
  4348. +}
  4349. +
  4350. +
  4351. +/****************************************************************************
  4352. +  checks whether a browser election is to be run on any workgroup
  4353. +  ***************************************************************************/
  4354. +BOOL check_elections(void)
  4355. +{
  4356. +    struct domain_record *d;
  4357. +    BOOL run_any_election = False;
  4358. +
  4359. +    for (d = domainlist; d; d = d->next)
  4360. +    {
  4361. +        struct work_record *work;
  4362. +        for (work = d->workgrouplist; work; work = work->next)
  4363. +        {
  4364. +            run_any_election |= work->RunningElection;
  4365. +
  4366. +            if (work->needelection && !work->RunningElection)
  4367. +            {
  4368. +                DEBUG(3,(">>> Starting election on %s <<<\n",work->work_group));
  4369. +                work->ElectionCount = 0;
  4370. +                work->RunningElection = True;
  4371. +                work->needelection = False;
  4372. +            }
  4373. +        }
  4374. +    }
  4375. +    return run_any_election;
  4376. +}
  4377. +
  4378. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/namequery.c samba-1.9.16alpha5/source/namequery.c
  4379. --- samba-1.9.16alpha4/source/namequery.c    Thu Jan  1 10:00:00 1970
  4380. +++ samba-1.9.16alpha5/source/namequery.c    Tue Jun  4 16:41:15 1996
  4381. @@ -0,0 +1,292 @@
  4382. +/* 
  4383. +   Unix SMB/Netbios implementation.
  4384. +   Version 1.9.
  4385. +   name query routines
  4386. +   Copyright (C) Andrew Tridgell 1994-1995
  4387. +   
  4388. +   This program is free software; you can redistribute it and/or modify
  4389. +   it under the terms of the GNU General Public License as published by
  4390. +   the Free Software Foundation; either version 2 of the License, or
  4391. +   (at your option) any later version.
  4392. +   
  4393. +   This program is distributed in the hope that it will be useful,
  4394. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4395. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4396. +   GNU General Public License for more details.
  4397. +   
  4398. +   You should have received a copy of the GNU General Public License
  4399. +   along with this program; if not, write to the Free Software
  4400. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4401. +   
  4402. +*/
  4403. +
  4404. +#include "includes.h"
  4405. +
  4406. +extern pstring scope;
  4407. +extern int DEBUGLEVEL;
  4408. +
  4409. +
  4410. +/****************************************************************************
  4411. +interpret a node status response
  4412. +****************************************************************************/
  4413. +static void _interpret_node_status(char *p, char *master,char *rname)
  4414. +{
  4415. +  int level = (master||rname)?4:0;
  4416. +  int numnames = CVAL(p,0);
  4417. +  DEBUG(level,("received %d names\n",numnames));
  4418. +
  4419. +  if (rname) *rname = 0;
  4420. +  if (master) *master = 0;
  4421. +
  4422. +  p += 1;
  4423. +  while (numnames--)
  4424. +    {
  4425. +      char qname[17];
  4426. +      int type;
  4427. +      fstring flags;
  4428. +      int i;
  4429. +      *flags = 0;
  4430. +      StrnCpy(qname,p,15);
  4431. +      type = CVAL(p,15);
  4432. +      p += 16;
  4433. +
  4434. +      strcat(flags, (p[0] & 0x80) ? "<GROUP> " : "        ");
  4435. +      if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
  4436. +      if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
  4437. +      if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
  4438. +      if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
  4439. +      if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
  4440. +      if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
  4441. +      if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
  4442. +      if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
  4443. +
  4444. +      if (master && !*master && type == 0x1d) {
  4445. +    StrnCpy(master,qname,15);
  4446. +    trim_string(master,NULL," ");
  4447. +      }
  4448. +
  4449. +      if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
  4450. +    StrnCpy(rname,qname,15);
  4451. +    trim_string(rname,NULL," ");
  4452. +      }
  4453. +      
  4454. +      for (i = strlen( qname) ; --i >= 0 ; ) {
  4455. +    if (!isprint(qname[i])) qname[i] = '.';
  4456. +      }
  4457. +      DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags));
  4458. +      p+=2;
  4459. +    }
  4460. +  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  4461. +           IVAL(p,20),IVAL(p,24)));
  4462. +}
  4463. +
  4464. +
  4465. +/****************************************************************************
  4466. +  do a netbios name status query on a host
  4467. +
  4468. +  the "master" parameter is a hack used for finding workgroups.
  4469. +  **************************************************************************/
  4470. +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  4471. +         struct in_addr to_ip,char *master,char *rname,
  4472. +         void (*fn)())
  4473. +{
  4474. +  BOOL found=False;
  4475. +  int retries = 2;
  4476. +  int retry_time = 5000;
  4477. +  struct timeval tval;
  4478. +  struct packet_struct p;
  4479. +  struct packet_struct *p2;
  4480. +  struct nmb_packet *nmb = &p.packet.nmb;
  4481. +  static int name_trn_id = 0;
  4482. +
  4483. +  bzero((char *)&p,sizeof(p));
  4484. +
  4485. +  if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
  4486. +    (getpid()%(unsigned)100);
  4487. +  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  4488. +
  4489. +  nmb->header.name_trn_id = name_trn_id;
  4490. +  nmb->header.opcode = 0;
  4491. +  nmb->header.response = False;
  4492. +  nmb->header.nm_flags.bcast = False;
  4493. +  nmb->header.nm_flags.recursion_available = 0;
  4494. +  nmb->header.nm_flags.recursion_desired = 1;
  4495. +  nmb->header.nm_flags.trunc = False;
  4496. +  nmb->header.nm_flags.authoritative = False;
  4497. +  nmb->header.rcode = 0;
  4498. +  nmb->header.qdcount = 1;
  4499. +  nmb->header.ancount = 0;
  4500. +  nmb->header.nscount = 0;
  4501. +  nmb->header.arcount = 0;
  4502. +
  4503. +  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  4504. +
  4505. +  nmb->question.question_type = 0x21;
  4506. +  nmb->question.question_class = 0x1;
  4507. +
  4508. +  p.ip = to_ip;
  4509. +  p.port = NMB_PORT;
  4510. +  p.fd = fd;
  4511. +  p.timestamp = time(NULL);
  4512. +  p.packet_type = NMB_PACKET;
  4513. +
  4514. +  GetTimeOfDay(&tval);
  4515. +
  4516. +  if (!send_packet(&p)) 
  4517. +    return(False);
  4518. +
  4519. +  retries--;
  4520. +
  4521. +  while (1)
  4522. +    {
  4523. +      struct timeval tval2;
  4524. +      GetTimeOfDay(&tval2);
  4525. +      if (TvalDiff(&tval,&tval2) > retry_time) {
  4526. +    if (!retries) break;
  4527. +    if (!found && !send_packet(&p))
  4528. +      return False;
  4529. +    GetTimeOfDay(&tval);
  4530. +    retries--;
  4531. +      }
  4532. +
  4533. +      if ((p2=receive_packet(fd,NMB_PACKET,90)))
  4534. +    {     
  4535. +      struct nmb_packet *nmb2 = &p2->packet.nmb;
  4536. +      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  4537. +          !nmb2->header.response) {
  4538. +        /* its not for us - maybe deal with it later */
  4539. +        if (fn) 
  4540. +          fn(p2);
  4541. +        else
  4542. +          free_packet(p2);
  4543. +        continue;
  4544. +      }
  4545. +      
  4546. +      if (nmb2->header.opcode != 0 ||
  4547. +          nmb2->header.nm_flags.bcast ||
  4548. +          nmb2->header.rcode ||
  4549. +          !nmb2->header.ancount ||
  4550. +          nmb2->answers->rr_type != 0x21) {
  4551. +        /* XXXX what do we do with this? could be a redirect, but
  4552. +           we'll discard it for the moment */
  4553. +        free_packet(p2);
  4554. +        continue;
  4555. +      }
  4556. +
  4557. +      _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
  4558. +      free_packet(p2);
  4559. +      return(True);
  4560. +    }
  4561. +    }
  4562. +  
  4563. +
  4564. +  DEBUG(0,("No status response (this is not unusual)\n"));
  4565. +
  4566. +  return(False);
  4567. +}
  4568. +
  4569. +
  4570. +/****************************************************************************
  4571. +  do a netbios name query to find someones IP
  4572. +  ****************************************************************************/
  4573. +BOOL name_query(int fd,char *name,int name_type, 
  4574. +        BOOL bcast,BOOL recurse,
  4575. +        struct in_addr to_ip, struct in_addr *ip,void (*fn)())
  4576. +{
  4577. +  BOOL found=False;
  4578. +  int retries = 3;
  4579. +  int retry_time = bcast?250:2000;
  4580. +  struct timeval tval;
  4581. +  struct packet_struct p;
  4582. +  struct packet_struct *p2;
  4583. +  struct nmb_packet *nmb = &p.packet.nmb;
  4584. +  static int name_trn_id = 0;
  4585. +
  4586. +  bzero((char *)&p,sizeof(p));
  4587. +
  4588. +  if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
  4589. +    (getpid()%(unsigned)100);
  4590. +  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  4591. +
  4592. +  nmb->header.name_trn_id = name_trn_id;
  4593. +  nmb->header.opcode = 0;
  4594. +  nmb->header.response = False;
  4595. +  nmb->header.nm_flags.bcast = bcast;
  4596. +  nmb->header.nm_flags.recursion_available = 0;
  4597. +  nmb->header.nm_flags.recursion_desired = 1;
  4598. +  nmb->header.nm_flags.trunc = False;
  4599. +  nmb->header.nm_flags.authoritative = False;
  4600. +  nmb->header.rcode = 0;
  4601. +  nmb->header.qdcount = 1;
  4602. +  nmb->header.ancount = 0;
  4603. +  nmb->header.nscount = 0;
  4604. +  nmb->header.arcount = 0;
  4605. +
  4606. +  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  4607. +
  4608. +  nmb->question.question_type = 0x20;
  4609. +  nmb->question.question_class = 0x1;
  4610. +
  4611. +  p.ip = to_ip;
  4612. +  p.port = NMB_PORT;
  4613. +  p.fd = fd;
  4614. +  p.timestamp = time(NULL);
  4615. +  p.packet_type = NMB_PACKET;
  4616. +
  4617. +  GetTimeOfDay(&tval);
  4618. +
  4619. +  if (!send_packet(&p)) 
  4620. +    return(False);
  4621. +
  4622. +  retries--;
  4623. +
  4624. +  while (1)
  4625. +    {
  4626. +      struct timeval tval2;
  4627. +      GetTimeOfDay(&tval2);
  4628. +      if (TvalDiff(&tval,&tval2) > retry_time) {
  4629. +    if (!retries) break;
  4630. +    if (!found && !send_packet(&p))
  4631. +      return False;
  4632. +    GetTimeOfDay(&tval);
  4633. +    retries--;
  4634. +      }
  4635. +
  4636. +      if ((p2=receive_packet(fd,NMB_PACKET,90)))
  4637. +    {     
  4638. +      struct nmb_packet *nmb2 = &p2->packet.nmb;
  4639. +      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  4640. +          !nmb2->header.response) {
  4641. +        /* its not for us - maybe deal with it later 
  4642. +           (put it on the queue?) */
  4643. +        if (fn) 
  4644. +          fn(p2);
  4645. +        else
  4646. +          free_packet(p2);
  4647. +        continue;
  4648. +      }
  4649. +      
  4650. +      if (nmb2->header.opcode != 0 ||
  4651. +          nmb2->header.nm_flags.bcast ||
  4652. +          nmb2->header.rcode ||
  4653. +          !nmb2->header.ancount) {
  4654. +        /* XXXX what do we do with this? could be a redirect, but
  4655. +           we'll discard it for the moment */
  4656. +        free_packet(p2);
  4657. +        continue;
  4658. +      }
  4659. +
  4660. +      if (ip) {
  4661. +        putip((char *)ip,&nmb2->answers->rdata[2]);
  4662. +        DEBUG(fn?3:2,("Got a positive name query response from %s",
  4663. +              inet_ntoa(p2->ip)));
  4664. +        DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
  4665. +      }
  4666. +      found=True; retries=0;
  4667. +      free_packet(p2);
  4668. +      if (fn) break;
  4669. +    }
  4670. +    }
  4671. +
  4672. +  return(found);
  4673. +}
  4674. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nameresp.c samba-1.9.16alpha5/source/nameresp.c
  4675. --- samba-1.9.16alpha4/source/nameresp.c    Thu Jan  1 10:00:00 1970
  4676. +++ samba-1.9.16alpha5/source/nameresp.c    Wed Jun  5 01:14:23 1996
  4677. @@ -0,0 +1,631 @@
  4678. +/* 
  4679. +   Unix SMB/Netbios implementation.
  4680. +   Version 1.9.
  4681. +   NBT netbios library routines
  4682. +   Copyright (C) Andrew Tridgell 1994-1995
  4683. +   
  4684. +   This program is free software; you can redistribute it and/or modify
  4685. +   it under the terms of the GNU General Public License as published by
  4686. +   the Free Software Foundation; either version 2 of the License, or
  4687. +   (at your option) any later version.
  4688. +   
  4689. +   This program is distributed in the hope that it will be useful,
  4690. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  4691. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  4692. +   GNU General Public License for more details.
  4693. +   
  4694. +   You should have received a copy of the GNU General Public License
  4695. +   along with this program; if not, write to the Free Software
  4696. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  4697. +   
  4698. +*/
  4699. +
  4700. +#include "includes.h"
  4701. +#include "localnet.h"
  4702. +#include "loadparm.h"
  4703. +
  4704. +/* this is our initiated name query response database */
  4705. +struct name_response_record *nameresponselist = NULL;
  4706. +
  4707. +extern struct in_addr myip;
  4708. +extern int DEBUGLEVEL;
  4709. +
  4710. +static uint16 name_trn_id=0;
  4711. +BOOL CanRecurse = True;
  4712. +extern pstring scope;
  4713. +extern pstring myname;
  4714. +extern struct in_addr ipzero;
  4715. +
  4716. +
  4717. +/***************************************************************************
  4718. +  add an initated name query  into the list
  4719. +  **************************************************************************/
  4720. +extern void add_response_record(struct name_response_record *n)
  4721. +{
  4722. +  struct name_response_record *n2;
  4723. +
  4724. +  if (!nameresponselist)
  4725. +    {
  4726. +      nameresponselist = n;
  4727. +      n->prev = NULL;
  4728. +      n->next = NULL;
  4729. +      return;
  4730. +    }
  4731. +  
  4732. +  for (n2 = nameresponselist; n2->next; n2 = n2->next) ;
  4733. +  
  4734. +  n2->next = n;
  4735. +  n->next = NULL;
  4736. +  n->prev = n2;
  4737. +}
  4738. +
  4739. +
  4740. +/*******************************************************************
  4741. +  remove old name response entries
  4742. +  ******************************************************************/
  4743. +void expire_netbios_response_entries(time_t t)
  4744. +{
  4745. +  struct name_response_record *n;
  4746. +  struct name_response_record *nextn;
  4747. +
  4748. +  for (n = nameresponselist; n; n = nextn)
  4749. +    {
  4750. +      if (n->start_time < t)
  4751. +    {
  4752. +      DEBUG(3,("Removing dead name query for %s %s (num_msgs=%d)\n",
  4753. +           inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
  4754. +
  4755. +      if (n->cmd_type == CHECK_MASTER && n->num_msgs == 0)
  4756. +        {
  4757. +          if (n->num_msgs > 1)
  4758. +        {
  4759. +          /* more than one master browser detected on a subnet.
  4760. +             there is a configuration problem. force an election */
  4761. +          struct domain_record *d;
  4762. +          if ((d = find_domain(n->to_ip)))
  4763. +            {
  4764. +              send_election(d,n->name.name,0,0,myname);
  4765. +            }
  4766. +        }
  4767. +          
  4768. +          /* if no response received, the master browser must have gone */
  4769. +          browser_gone(n->name.name, n->to_ip);
  4770. +        }
  4771. +      
  4772. +      nextn = n->next;
  4773. +      
  4774. +      if (n->prev) n->prev->next = n->next;
  4775. +      if (n->next) n->next->prev = n->prev;
  4776. +      
  4777. +      if (nameresponselist == n) nameresponselist = n->next; 
  4778. +      
  4779. +      free(n);
  4780. +    }
  4781. +      else
  4782. +    {
  4783. +      nextn = n->next;
  4784. +    }
  4785. +    }
  4786. +}
  4787. +
  4788. +
  4789. +/****************************************************************************
  4790. +  reply to a netbios name packet 
  4791. +  ****************************************************************************/
  4792. +void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,int opcode,
  4793. +              struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
  4794. +              char *data,int len)
  4795. +{
  4796. +  struct packet_struct p;
  4797. +  struct nmb_packet *nmb = &p.packet.nmb;
  4798. +  struct res_rec answers;
  4799. +  char *packet_type = "unknown";
  4800. +  
  4801. +  p = *p1;
  4802. +
  4803. +  if (rr_type == NMB_STATUS) packet_type = "nmb_status";
  4804. +  if (rr_type == NMB_QUERY ) packet_type = "nmb_query";
  4805. +  if (rr_type == NMB_REG   ) packet_type = "nmb_reg";
  4806. +  if (rr_type == NMB_REL   ) packet_type = "nmb_rel";
  4807. +  
  4808. +  DEBUG(4,("replying netbios packet: %s %s\n",
  4809. +       packet_type, namestr(rr_name), inet_ntoa(p.ip)));
  4810. +
  4811. +  nmb->header.name_trn_id = trn_id;
  4812. +  nmb->header.opcode = opcode;
  4813. +  nmb->header.response = True;
  4814. +  nmb->header.nm_flags.bcast = False;
  4815. +  nmb->header.nm_flags.recursion_available = True;
  4816. +  nmb->header.nm_flags.recursion_desired = True;
  4817. +  nmb->header.nm_flags.trunc = False;
  4818. +  nmb->header.nm_flags.authoritative = True;
  4819. +  
  4820. +  nmb->header.qdcount = 0;
  4821. +  nmb->header.ancount = 1;
  4822. +  nmb->header.nscount = 0;
  4823. +  nmb->header.arcount = 0;
  4824. +  nmb->header.rcode = 0;
  4825. +  
  4826. +  bzero((char*)&nmb->question,sizeof(nmb->question));
  4827. +  
  4828. +  nmb->answers = &answers;
  4829. +  bzero((char*)nmb->answers,sizeof(*nmb->answers));
  4830. +  
  4831. +  nmb->answers->rr_name  = *rr_name;
  4832. +  nmb->answers->rr_type  = rr_type;
  4833. +  nmb->answers->rr_class = rr_class;
  4834. +  nmb->answers->ttl      = ttl;
  4835. +  
  4836. +  if (data && len)
  4837. +    {
  4838. +      nmb->answers->rdlength = len;
  4839. +      memcpy(nmb->answers->rdata, data, len);
  4840. +    }
  4841. +  
  4842. +  p.packet_type = NMB_PACKET;
  4843. +  
  4844. +  debug_nmb_packet(&p);
  4845. +  
  4846. +  send_packet(&p);
  4847. +}
  4848. +
  4849. +
  4850. +/****************************************************************************
  4851. +  initiate a netbios packet
  4852. +  ****************************************************************************/
  4853. +uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
  4854. +                   int nb_flags,BOOL bcast,BOOL recurse,struct in_addr to_ip)
  4855. +{
  4856. +  struct packet_struct p;
  4857. +  struct nmb_packet *nmb = &p.packet.nmb;
  4858. +  struct res_rec additional_rec;
  4859. +  char *packet_type = "unknown";
  4860. +  int opcode = -1;
  4861. +
  4862. +  if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
  4863. +  if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
  4864. +  if (quest_type == NMB_REG   ) { packet_type = "nmb_reg"; opcode = 5; }
  4865. +  if (quest_type == NMB_REL   ) { packet_type = "nmb_rel"; opcode = 6; }
  4866. +  
  4867. +  DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
  4868. +       packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
  4869. +
  4870. +  if (opcode == -1) return False;
  4871. +
  4872. +  bzero((char *)&p,sizeof(p));
  4873. +
  4874. +  if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
  4875. +    (getpid()%(unsigned)100);
  4876. +  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  4877. +
  4878. +  nmb->header.name_trn_id = name_trn_id;
  4879. +  nmb->header.opcode = opcode;
  4880. +  nmb->header.response = False;
  4881. +  nmb->header.nm_flags.bcast = bcast;
  4882. +  nmb->header.nm_flags.recursion_available = CanRecurse;
  4883. +  nmb->header.nm_flags.recursion_desired = recurse;
  4884. +  nmb->header.nm_flags.trunc = False;
  4885. +  nmb->header.nm_flags.authoritative = False;
  4886. +  nmb->header.rcode = 0;
  4887. +  nmb->header.qdcount = 1;
  4888. +  nmb->header.ancount = 0;
  4889. +  nmb->header.nscount = 0;
  4890. +  nmb->header.arcount = (quest_type==NMB_REG || quest_type==NMB_REL) ? 1 : 0;
  4891. +  
  4892. +  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  4893. +  
  4894. +  nmb->question.question_type = quest_type;
  4895. +  nmb->question.question_class = 0x1;
  4896. +  
  4897. +  if (quest_type == NMB_REG || quest_type == NMB_REL)
  4898. +    {
  4899. +      nmb->additional = &additional_rec;
  4900. +      bzero((char *)nmb->additional,sizeof(*nmb->additional));
  4901. +      
  4902. +      nmb->additional->rr_name  = nmb->question.question_name;
  4903. +      nmb->additional->rr_type  = nmb->question.question_type;
  4904. +      nmb->additional->rr_class = nmb->question.question_class;
  4905. +      
  4906. +      nmb->additional->ttl = quest_type == NMB_REG ? lp_max_ttl() : 0;
  4907. +      nmb->additional->rdlength = 6;
  4908. +      nmb->additional->rdata[0] = nb_flags;
  4909. +      putip(&nmb->additional->rdata[2],(char *)&myip);
  4910. +    }
  4911. +  
  4912. +  p.ip = to_ip;
  4913. +  p.port = NMB_PORT;
  4914. +  p.fd = fd;
  4915. +  p.timestamp = time(NULL);
  4916. +  p.packet_type = NMB_PACKET;
  4917. +  
  4918. +  if (!send_packet(&p)) 
  4919. +    return(0);
  4920. +  
  4921. +  return(name_trn_id);
  4922. +}
  4923. +
  4924. +
  4925. +/****************************************************************************
  4926. +  wrapper function to override a broadcast message and send it to the WINS
  4927. +  name server instead, if it exists. if wins is false, and there has been no
  4928. +  WINS server specified, the packet will NOT be sent.
  4929. +  ****************************************************************************/
  4930. +void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
  4931. +                char *name,int name_type,int nb_flags,
  4932. +                BOOL bcast,BOOL recurse,struct in_addr to_ip)
  4933. +{
  4934. +  if ((!lp_wins_support()) && (*lp_wins_server()))
  4935. +    {
  4936. +      /* samba is not a WINS server, and we are using a WINS server */
  4937. +      struct in_addr wins_ip;
  4938. +      wins_ip = *interpret_addr2(lp_wins_server());
  4939. +
  4940. +      if (!zero_ip(wins_ip))
  4941. +    {
  4942. +      bcast = False;
  4943. +      to_ip = wins_ip;
  4944. +    }
  4945. +      else
  4946. +    {
  4947. +      /* oops. smb.conf's wins server parameter MUST be a host_name 
  4948. +         or an ip_address. */
  4949. +      DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
  4950. +    }
  4951. +    }
  4952. +
  4953. +  if (zero_ip(to_ip)) return;
  4954. +
  4955. +  queue_netbios_packet(fd, quest_type, cmd, 
  4956. +               name, name_type, nb_flags,
  4957. +               bcast, recurse, to_ip);
  4958. +}
  4959. +
  4960. +/****************************************************************************
  4961. +  create a name query response record
  4962. +  **************************************************************************/
  4963. +static struct name_response_record *make_name_query_record(
  4964. +                               enum cmd_type cmd,int id,int fd,
  4965. +                               char *name,int type,
  4966. +                               BOOL bcast,BOOL recurse,
  4967. +                               struct in_addr ip)
  4968. +{
  4969. +  struct name_response_record *n;
  4970. +    
  4971. +  if (!name || !name[0]) return NULL;
  4972. +    
  4973. +  if (!(n = (struct name_response_record *)malloc(sizeof(*n)))) 
  4974. +    return(NULL);
  4975. +
  4976. +  n->response_id = id;
  4977. +  n->cmd_type = cmd;
  4978. +  n->fd = fd;
  4979. +  make_nmb_name(&n->name, name, type, scope);
  4980. +  n->bcast = bcast;
  4981. +  n->recurse = recurse;
  4982. +  n->to_ip = ip;
  4983. +  n->start_time = time(NULL);
  4984. +  n->num_msgs = 0;
  4985. +
  4986. +  return n;
  4987. +}
  4988. +
  4989. +
  4990. +/****************************************************************************
  4991. +  initiate a netbios name query to find someone's or someones' IP
  4992. +  this is intended to be used (not exclusively) for broadcasting to
  4993. +  master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
  4994. +  complete lists across a wide area network
  4995. +  ****************************************************************************/
  4996. +void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
  4997. +              int name_type,int nb_flags,BOOL bcast,BOOL recurse,
  4998. +              struct in_addr to_ip)
  4999. +{
  5000. +  uint16 id = initiate_netbios_packet(fd, quest_type, name, name_type,
  5001. +                      nb_flags, bcast, recurse, to_ip);
  5002. +  struct name_response_record *n;
  5003. +
  5004. +  if (id == 0) return;
  5005. +  
  5006. +  if ((n = 
  5007. +       make_name_query_record(cmd,id,fd,name,name_type,bcast,recurse,to_ip)))
  5008. +    {
  5009. +      add_response_record(n);
  5010. +    }
  5011. +}
  5012. +
  5013. +
  5014. +/****************************************************************************
  5015. +  find a response in the name query response list
  5016. +  **************************************************************************/
  5017. +struct name_response_record *find_name_query(uint16 id)
  5018. +{   
  5019. +  struct name_response_record *n;
  5020. +
  5021. +  for (n = nameresponselist; n; n = n->next)
  5022. +    {
  5023. +      if (n->response_id == id)    {
  5024. +    return n;
  5025. +      }
  5026. +    }
  5027. +
  5028. +  return NULL;
  5029. +}
  5030. +
  5031. +
  5032. +/*******************************************************************
  5033. +  the global packet linked-list. incoming entries are added to the
  5034. +  end of this list.  it is supposed to remain fairly short so we
  5035. +  won't bother with an end pointer.
  5036. +  ******************************************************************/
  5037. +static struct packet_struct *packet_queue = NULL;
  5038. +
  5039. +/*******************************************************************
  5040. +  queue a packet into the packet queue
  5041. +  ******************************************************************/
  5042. +void queue_packet(struct packet_struct *packet)
  5043. +{
  5044. +  struct packet_struct *p;
  5045. +
  5046. +  if (!packet_queue) {
  5047. +    packet->prev = NULL;
  5048. +    packet->next = NULL;
  5049. +    packet_queue = packet;
  5050. +    return;
  5051. +  }
  5052. +  
  5053. +  /* find the bottom */
  5054. +  for (p=packet_queue;p->next;p=p->next) ;
  5055. +
  5056. +  p->next = packet;
  5057. +  packet->next = NULL;
  5058. +  packet->prev = p;
  5059. +}
  5060. +
  5061. +/*******************************************************************
  5062. +  run elements off the packet queue till its empty
  5063. +  ******************************************************************/
  5064. +void run_packet_queue()
  5065. +{
  5066. +  struct packet_struct *p;
  5067. +
  5068. +  while ((p=packet_queue))
  5069. +    {
  5070. +      switch (p->packet_type)
  5071. +    {
  5072. +    case NMB_PACKET:
  5073. +      process_nmb(p);
  5074. +      break;
  5075. +      
  5076. +    case DGRAM_PACKET:
  5077. +      process_dgram(p);
  5078. +      break;
  5079. +    }
  5080. +      
  5081. +      packet_queue = packet_queue->next;
  5082. +      if (packet_queue) packet_queue->prev = NULL;
  5083. +      free_packet(p);
  5084. +    }
  5085. +}
  5086. +
  5087. +/****************************************************************************
  5088. +  listens for NMB or DGRAM packets, and queues them
  5089. +  ***************************************************************************/
  5090. +void listen_for_packets(BOOL run_election)
  5091. +{
  5092. +  fd_set fds;
  5093. +  int selrtn;
  5094. +  struct timeval timeout;
  5095. +
  5096. +  FD_ZERO(&fds);
  5097. +  FD_SET(ClientNMB,&fds);
  5098. +  FD_SET(ClientDGRAM,&fds);
  5099. +
  5100. +  /* during elections we need to send election packets at one
  5101. +     second intervals */
  5102. +
  5103. +  timeout.tv_sec = run_election ? 1 : NMBD_SELECT_LOOP;
  5104. +  timeout.tv_usec = 0;
  5105. +
  5106. +  selrtn = sys_select(&fds,&timeout);
  5107. +
  5108. +  if (FD_ISSET(ClientNMB,&fds))
  5109. +    {
  5110. +      struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
  5111. +      if (packet) {
  5112. +#if 0
  5113. +    if (ip_equal(packet->ip,myip) &&
  5114. +        (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
  5115. +      DEBUG(3,("discarding packet from %s:%d\n",
  5116. +           inet_ntoa(packet->ip),packet->port));      
  5117. +      DEBUG(3,("myip=%s eq=%d\n",
  5118. +           inet_ntoa(myip),ip_equal(packet->ip,myip)));
  5119. +      free_packet(packet);
  5120. +    } else 
  5121. +#endif
  5122. +      {
  5123. +        queue_packet(packet);
  5124. +      }
  5125. +      }
  5126. +    }
  5127. +
  5128. +  if (FD_ISSET(ClientDGRAM,&fds))
  5129. +    {
  5130. +      struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
  5131. +      if (packet) {
  5132. +#if 0
  5133. +    if (ip_equal(packet->ip,myip) &&
  5134. +          (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
  5135. +      DEBUG(3,("discarding packet from %s:%d\n",
  5136. +           inet_ntoa(packet->ip),packet->port));      
  5137. +      DEBUG(3,("myip=%s eq=%d\n",
  5138. +           inet_ntoa(myip),ip_equal(packet->ip,myip)));
  5139. +      free_packet(packet);
  5140. +    } else
  5141. +#endif 
  5142. +      {
  5143. +        queue_packet(packet);
  5144. +      }
  5145. +      }
  5146. +    }
  5147. +}
  5148. +
  5149. +
  5150. +
  5151. +/****************************************************************************
  5152. +interpret a node status response. this is pretty hacked: we need two bits of
  5153. +info. a) the name of the workgroup b) the name of the server. it will also
  5154. +add all the names it finds into the namelist.
  5155. +****************************************************************************/
  5156. +BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
  5157. +               char *serv_name, struct in_addr ip)
  5158. +{
  5159. +  int level = t==0x20 ? 4 : 0;
  5160. +  int numnames = CVAL(p,0);
  5161. +  BOOL found = False;
  5162. +
  5163. +  DEBUG(level,("received %d names\n",numnames));
  5164. +
  5165. +  p += 1;
  5166. +
  5167. +  if (serv_name) *serv_name = 0;
  5168. +
  5169. +  while (numnames--)
  5170. +    {
  5171. +      char qname[17];
  5172. +      int type;
  5173. +      fstring flags;
  5174. +      int nb_flags;
  5175. +      
  5176. +      BOOL group = False;
  5177. +      BOOL add   = False;
  5178. +      
  5179. +      *flags = 0;
  5180. +      
  5181. +      StrnCpy(qname,p,15);
  5182. +      type = CVAL(p,15);
  5183. +      nb_flags = p[16];
  5184. +      
  5185. +      p += 18;
  5186. +      
  5187. +      if (NAME_GROUP    (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
  5188. +      if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
  5189. +      if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
  5190. +      if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
  5191. +      if (NAME__FLAG    (nb_flags)) { strcat(flags,"_ "); }
  5192. +      if (NAME_DEREG    (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
  5193. +      if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
  5194. +      if (NAME_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
  5195. +      if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
  5196. +      
  5197. +      /* might as well update our namelist while we're at it */
  5198. +      if (add)
  5199. +    {
  5200. +      struct in_addr nameip;
  5201. +      enum name_source src;
  5202. +      
  5203. +      if (ip_equal(ip, myip))
  5204. +        {
  5205. +          nameip = ipzero;
  5206. +          src = SELF;
  5207. +        }
  5208. +      else
  5209. +        {
  5210. +          nameip = ip;
  5211. +          src = STATUS_QUERY;
  5212. +        }
  5213. +      add_netbios_entry(qname,type,nb_flags,2*60*60,src,nameip);
  5214. +    } 
  5215. +
  5216. +      /* we want the server name */
  5217. +      if (serv_name && !*serv_name && !group && t == 0)
  5218. +    {
  5219. +      StrnCpy(serv_name,qname,15);
  5220. +      serv_name[15] = 0;
  5221. +    }
  5222. +      
  5223. +      /* looking for a name and type? */
  5224. +      if (name && !found && (t == type))
  5225. +    {
  5226. +      /* take a guess at some of the name types we're going to ask for.
  5227. +         evaluate whether they are group names or no... */
  5228. +      if (((t == 0x1b || t == 0x1d             ) && !group) ||
  5229. +          ((t == 0x20 || t == 0x1c || t == 0x1e) &&  group))
  5230. +        {
  5231. +          found = True;
  5232. +          make_nmb_name(name,qname,type,scope);
  5233. +        }
  5234. +    }
  5235. +      
  5236. +      DEBUG(level,("\t%s(0x%x)\t%s\n",qname,type,flags));
  5237. +    }
  5238. +  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  5239. +           IVAL(p,20),IVAL(p,24)));
  5240. +  return found;
  5241. +}
  5242. +
  5243. +
  5244. +/****************************************************************************
  5245. +  construct and send a netbios DGRAM
  5246. +
  5247. +  Note that this currently sends all answers to port 138. thats the
  5248. +  wrong things to do! I should send to the requestors port. XXX
  5249. +  **************************************************************************/
  5250. +BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
  5251. +             char *dstname,int src_type,int dest_type,
  5252. +             struct in_addr dest_ip,struct in_addr src_ip)
  5253. +{
  5254. +  struct packet_struct p;
  5255. +  struct dgram_packet *dgram = &p.packet.dgram;
  5256. +  char *ptr,*p2;
  5257. +  char tmp[4];
  5258. +
  5259. +  bzero((char *)&p,sizeof(p));
  5260. +
  5261. +  dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
  5262. +  dgram->header.flags.node_type = M_NODE;
  5263. +  dgram->header.flags.first = True;
  5264. +  dgram->header.flags.more = False;
  5265. +  dgram->header.dgm_id = name_trn_id++;
  5266. +  dgram->header.source_ip = src_ip;
  5267. +  dgram->header.source_port = DGRAM_PORT;
  5268. +  dgram->header.dgm_length = 0; /* let build_dgram() handle this */
  5269. +  dgram->header.packet_offset = 0;
  5270. +  
  5271. +  make_nmb_name(&dgram->source_name,srcname,src_type,scope);
  5272. +  make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
  5273. +
  5274. +  ptr = &dgram->data[0];
  5275. +
  5276. +  /* now setup the smb part */
  5277. +  ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
  5278. +  memcpy(tmp,ptr,4);
  5279. +  set_message(ptr,17,17 + len,True);
  5280. +  memcpy(ptr,tmp,4);
  5281. +
  5282. +  CVAL(ptr,smb_com) = SMBtrans;
  5283. +  SSVAL(ptr,smb_vwv1,len);
  5284. +  SSVAL(ptr,smb_vwv11,len);
  5285. +  SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
  5286. +  SSVAL(ptr,smb_vwv13,3);
  5287. +  SSVAL(ptr,smb_vwv14,1);
  5288. +  SSVAL(ptr,smb_vwv15,1);
  5289. +  SSVAL(ptr,smb_vwv16,2);
  5290. +  p2 = smb_buf(ptr);
  5291. +  strcpy(p2,mailslot);
  5292. +  p2 = skip_string(p2,1);
  5293. +
  5294. +  memcpy(p2,buf,len);
  5295. +  p2 += len;
  5296. +
  5297. +  dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
  5298. +
  5299. +  p.ip = dest_ip;
  5300. +  p.port = DGRAM_PORT;
  5301. +  p.fd = ClientDGRAM;
  5302. +  p.timestamp = time(NULL);
  5303. +  p.packet_type = DGRAM_PACKET;
  5304. +
  5305. +  return(send_packet(&p));
  5306. +}
  5307. +
  5308. +
  5309. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nameserv.c samba-1.9.16alpha5/source/nameserv.c
  5310. --- samba-1.9.16alpha4/source/nameserv.c    Sat Jun  1 01:15:12 1996
  5311. +++ samba-1.9.16alpha5/source/nameserv.c    Wed Jun  5 01:16:27 1996
  5312. @@ -18,202 +18,32 @@
  5313.     along with this program; if not, write to the Free Software
  5314.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  5315.     
  5316. +   Revision History:
  5317. +
  5318. +   14 jan 96: lkcl@pires.co.uk
  5319. +   added multiple workgroup domain master support
  5320. +
  5321.  */
  5322.  
  5323.  #include "includes.h"
  5324.  #include "loadparm.h"
  5325. -#include "nameserv.h"
  5326. +#include "localnet.h"
  5327.  
  5328.  
  5329. -static void queue_packet(struct packet_struct *packet);
  5330. -void process(void);
  5331. -static void dump_names(void);
  5332. -static void announce_request(char *group);
  5333. -void sync_browse_lists(char *name,int name_type,char *myname,
  5334. -               char *domain,struct in_addr ip);
  5335. +enum name_search { FIND_SELF, FIND_GLOBAL };
  5336.  
  5337.  extern int DEBUGLEVEL;
  5338.  
  5339. -extern pstring debugf;
  5340. -pstring servicesf = CONFIGFILE;
  5341. -
  5342.  extern pstring scope;
  5343. -
  5344.  extern BOOL CanRecurse;
  5345. +extern pstring myname;
  5346. +extern struct in_addr ipzero;
  5347.  
  5348. -extern struct in_addr myip;
  5349. -extern struct in_addr bcast_ip;
  5350. -extern struct in_addr Netmask;
  5351. -extern pstring myhostname;
  5352. -static pstring host_file;
  5353. -static pstring myname="";
  5354. -
  5355. -static int ClientNMB= -1;
  5356. -static int ClientDGRAM= -1;
  5357. -
  5358. -static BOOL needannounce=True;
  5359. -
  5360. -/* this is our name database */
  5361. -static struct name_record *namelist = NULL;
  5362. -
  5363. -/* list of servers to be returned by NetServerEnum */
  5364. -static struct server_record *serverlist = NULL;
  5365. -
  5366. -/* this is the domain list. For the moment we will assume that our
  5367. -   primary domain is the first one listed in this list */
  5368. -static struct domain_record *domainlist = NULL;
  5369. -
  5370. -/* are we running as a daemon ? */
  5371. -static BOOL is_daemon = False;
  5372. -
  5373. -/* machine comment for host announcements */
  5374. -static pstring ServerComment="";
  5375. -
  5376. -static BOOL got_bcast = False;
  5377. -static BOOL got_myip = False;
  5378. -static BOOL got_nmask = False;
  5379. -
  5380. -static BOOL updatedlists = False;
  5381. -static int  updatecount=0;
  5382. -
  5383. -/* what server type are we currently */
  5384. -static int ServerType = 
  5385. -SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_TIME_SOURCE |
  5386. -SV_TYPE_SERVER_UNIX |
  5387. -SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER;
  5388. -
  5389. -/* here are my election parameters */
  5390. -
  5391. -/* NTAS uses 2, NT uses 1, WfWg uses 0 */
  5392. -#define MAINTAIN_LIST 1
  5393. -#define ELECTION_VERSION 1
  5394. -
  5395. -static BOOL RunningElection = False;
  5396. -static BOOL needelection = False;
  5397. -static int ElectionCount = 0;
  5398. -static int StartupTime =0;
  5399. -
  5400. -
  5401. -/* WfWg uses 01040b01 */
  5402. -/* Win95 uses 01041501 */
  5403. -/* NTAS uses ?? */
  5404. -static uint32 ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
  5405. -
  5406. -/* we currently support being the master for just one group. Being the
  5407. -   master for more than one group might be tricky as NetServerEnum is
  5408. -   often asked for a list without naming the group */
  5409. -static fstring PrimaryGroup="";
  5410. -
  5411. -#define AM_MASTER (PrimaryGroup[0] && (ServerType & SV_TYPE_MASTER_BROWSER))
  5412. -
  5413. -#define MSBROWSE "\001\002__MSBROWSE__\002"
  5414. +/* netbios names database */
  5415. +struct name_record *namelist;
  5416.  
  5417.  #define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
  5418.  
  5419. -#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  5420. -
  5421. -/****************************************************************************
  5422. -catch a sighup
  5423. -****************************************************************************/
  5424. -static int sig_hup()
  5425. -{
  5426. -  BlockSignals(True);
  5427. -
  5428. -  DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
  5429. -  dump_names();
  5430. -  reload_services(True);
  5431. -
  5432. -  BlockSignals(False);
  5433. -#ifndef DONT_REINSTALL_SIG
  5434. -  signal(SIGHUP,SIGNAL_CAST sig_hup);
  5435. -#endif
  5436. -  return(0);
  5437. -}
  5438. -
  5439. -/****************************************************************************
  5440. -catch a sigpipe
  5441. -****************************************************************************/
  5442. -static int sig_pipe()
  5443. -{
  5444. -  BlockSignals(True);
  5445. -
  5446. -  DEBUG(0,("Got SIGPIPE\n"));
  5447. -  if (!is_daemon)
  5448. -    exit(1);
  5449. -  BlockSignals(False);
  5450. -  return(0);
  5451. -}
  5452. -
  5453. -#if DUMP_CORE
  5454. -/*******************************************************************
  5455. -prepare to dump a core file - carefully!
  5456. -********************************************************************/
  5457. -static BOOL dump_core(void)
  5458. -{
  5459. -  char *p;
  5460. -  pstring dname;
  5461. -  strcpy(dname,debugf);
  5462. -  if ((p=strrchr(dname,'/'))) *p=0;
  5463. -  strcat(dname,"/corefiles");
  5464. -  mkdir(dname,0700);
  5465. -  sys_chown(dname,getuid(),getgid());
  5466. -  chmod(dname,0700);
  5467. -  if (chdir(dname)) return(False);
  5468. -  umask(~(0700));
  5469. -
  5470. -#ifndef NO_GETRLIMIT
  5471. -#ifdef RLIMIT_CORE
  5472. -  {
  5473. -    struct rlimit rlp;
  5474. -    getrlimit(RLIMIT_CORE, &rlp);
  5475. -    rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
  5476. -    setrlimit(RLIMIT_CORE, &rlp);
  5477. -    getrlimit(RLIMIT_CORE, &rlp);
  5478. -    DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
  5479. -  }
  5480. -#endif
  5481. -#endif
  5482. -
  5483. -
  5484. -  DEBUG(0,("Dumping core in %s\n",dname));
  5485. -  return(True);
  5486. -}
  5487. -#endif
  5488. -
  5489. -
  5490. -/****************************************************************************
  5491. -possibly continue after a fault
  5492. -****************************************************************************/
  5493. -static void fault_continue(void)
  5494. -{
  5495. -  static int errcount=1;
  5496. -
  5497. -  errcount--;
  5498. -
  5499. -  if (is_daemon && errcount)
  5500. -    process();
  5501. -
  5502. -#if DUMP_CORE
  5503. -    if (dump_core()) return;
  5504. -#endif
  5505. -
  5506. -  return;
  5507. -}
  5508. -
  5509. -
  5510. -/*******************************************************************
  5511. -  wrapper to get the DC
  5512. -  ******************************************************************/
  5513. -static char *domain_controller(void)
  5514. -{
  5515. -  char *dc = lp_domain_controller();
  5516. -  /* so many people mistake this for a bool that we need to handle it. sigh. */
  5517. -  if (!*dc || strequal(dc,"yes") || strequal(dc,"true"))
  5518. -    strcpy(dc,myname);
  5519. -  return(dc);
  5520. -}
  5521. -
  5522. -
  5523.  
  5524.  /****************************************************************************
  5525.    true if two netbios names are equal
  5526. @@ -232,7 +62,8 @@
  5527.  {
  5528.    struct name_record *n2;
  5529.  
  5530. -  if (!namelist) {
  5531. +  if (!namelist)
  5532. +  {
  5533.      namelist = n;
  5534.      n->prev = NULL;
  5535.      n->next = NULL;
  5536. @@ -247,57 +78,17 @@
  5537.  }
  5538.  
  5539.  /****************************************************************************
  5540. -  add a domain into the list
  5541. -  **************************************************************************/
  5542. -static void add_domain(struct domain_record *d)
  5543. -{
  5544. -  struct domain_record *d2;
  5545. -
  5546. -  if (!domainlist) {
  5547. -    domainlist = d;
  5548. -    d->prev = NULL;
  5549. -    d->next = NULL;
  5550. -    return;
  5551. -  }
  5552. -
  5553. -  for (d2 = domainlist; d2->next; d2 = d2->next) ;
  5554. -
  5555. -  d2->next = d;
  5556. -  d->next = NULL;
  5557. -  d->prev = d2;
  5558. -}
  5559. -
  5560. -
  5561. -/****************************************************************************
  5562. -  add a server into the list
  5563. -  **************************************************************************/
  5564. -static void add_server(struct server_record *s)
  5565. -{
  5566. -  struct server_record *s2;
  5567. -
  5568. -  if (!serverlist) {
  5569. -    serverlist = s;
  5570. -    s->prev = NULL;
  5571. -    s->next = NULL;
  5572. -    return;
  5573. -  }
  5574. -
  5575. -  for (s2 = serverlist; s2->next; s2 = s2->next) ;
  5576. -
  5577. -  s2->next = s;
  5578. -  s->next = NULL;
  5579. -  s->prev = s2;
  5580. -}
  5581. -
  5582. -/****************************************************************************
  5583.    remove a name from the namelist. The pointer must be an element just 
  5584.    retrieved
  5585.    **************************************************************************/
  5586. -static void remove_name(struct name_record *n)
  5587. +void remove_name(struct name_record *n)
  5588.  {
  5589.    struct name_record *nlist = namelist;
  5590. +
  5591.    while (nlist && nlist != n) nlist = nlist->next;
  5592. -  if (nlist) {
  5593. +
  5594. +  if (nlist)
  5595. +  {
  5596.      if (nlist->next) nlist->next->prev = nlist->prev;
  5597.      if (nlist->prev) nlist->prev->next = nlist->next;
  5598.      free(nlist);
  5599. @@ -305,48 +96,80 @@
  5600.  }
  5601.  
  5602.  /****************************************************************************
  5603. -  find a name in the namelist 
  5604. +  find a name in the domain database namelist 
  5605. +  search can be:
  5606. +  FIND_SELF   - look for names the samba server has added for itself
  5607. +  FIND_GLOBAL - the name can be anyone. first look on the client's
  5608. +                subnet, then the server's subnet, then all subnets.
  5609.    **************************************************************************/
  5610. -static struct name_record *find_name(struct nmb_name *n)
  5611. +static struct name_record *find_name_search(struct nmb_name *name, enum name_search search,
  5612. +                        struct in_addr ip)
  5613.  {
  5614. -  struct name_record *ret;
  5615. -  for (ret = namelist; ret; ret = ret->next)
  5616. -    if (name_equal(&ret->name,n)) return(ret);
  5617. +    struct name_record *ret;
  5618. +
  5619. +    /* any number of winpopup names can be added. must search by ip as well */
  5620. +    if (name->name_type != 0x3) ip = ipzero;
  5621. +
  5622. +    for (ret = namelist; ret; ret = ret->next)
  5623. +    {
  5624. +        if (name_equal(&ret->name,name))
  5625. +        {
  5626. +            /* self search: self names only */
  5627. +            if (search == FIND_SELF && ret->source != SELF) continue;
  5628. +
  5629. +            if (zero_ip(ip) || ip_equal(ip, ret->ip))
  5630. +            {
  5631. +                return ret;
  5632. +            }
  5633. +        }
  5634. +    }
  5635.  
  5636. -  return(NULL);
  5637. +    return NULL;
  5638.  }
  5639.  
  5640. +
  5641.  /****************************************************************************
  5642.    dump a copy of the name table
  5643.    **************************************************************************/
  5644. -static void dump_names(void)
  5645. +void dump_names(void)
  5646.  {
  5647. -  time_t t = time(NULL);
  5648. -  struct name_record *n;
  5649. -  struct domain_record *d;
  5650. +    struct name_record *n;
  5651. +    time_t t = time(NULL);
  5652.  
  5653. -  DEBUG(3,("Dump of local name table:\n"));
  5654. +    DEBUG(3,("Dump of local name table:\n"));
  5655. +
  5656. +    for (n = namelist; n; n = n->next)
  5657. +    {
  5658. +        DEBUG(3,("%s %s TTL=%d NBFLAGS=%2x\n",
  5659. +                namestr(&n->name),
  5660. +                inet_ntoa(n->ip),
  5661. +                n->death_time?n->death_time-t:0,
  5662. +                n->nb_flags));
  5663. +    }
  5664. +}
  5665.  
  5666. -  for (n = namelist; n; n = n->next) {
  5667. -    DEBUG(3,("%s %s TTL=%d Unique=%s\n",
  5668. -         namestr(&n->name),
  5669. -         inet_ntoa(n->ip),
  5670. -         n->death_time?n->death_time-t:0,
  5671. -         BOOLSTR(n->unique)));
  5672. -    }
  5673.  
  5674. -  DEBUG(3,("\nDump of domain list:\n"));
  5675. -  for (d = domainlist; d; d = d->next)
  5676. -    DEBUG(3,("%s %s\n",d->name,inet_ntoa(d->bcast_ip)));
  5677. +/****************************************************************************
  5678. +  remove an entry from the name list
  5679. +  ****************************************************************************/
  5680. +void remove_netbios_name(char *name,int type, enum name_source source,
  5681. +             struct in_addr ip)
  5682. +{
  5683. +    struct nmb_name nn;
  5684. +    struct name_record *n;
  5685. +
  5686. +    make_nmb_name(&nn, name, type, scope);
  5687. +    n = find_name_search(&nn, FIND_GLOBAL, ip);
  5688. +
  5689. +    if (n && n->source == source) remove_name(n);
  5690.  }
  5691.  
  5692.  
  5693.  /****************************************************************************
  5694. -  add a host entry to the name list
  5695. +  add an entry to the name list
  5696.    ****************************************************************************/
  5697. -static struct name_record *add_host_entry(char *name,int type,BOOL unique,int ttl,
  5698. -                      enum name_source source,
  5699. -                      struct in_addr ip)
  5700. +struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int ttl,
  5701. +                      enum name_source source, struct in_addr ip)
  5702.  {
  5703.    struct name_record *n;
  5704.    struct name_record *n2=NULL;
  5705. @@ -357,1364 +180,431 @@
  5706.    bzero((char *)n,sizeof(*n));
  5707.  
  5708.    make_nmb_name(&n->name,name,type,scope);
  5709. -  if ((n2=find_name(&n->name))) {
  5710. +
  5711. +  if ((n2 = find_name_search(&n->name, FIND_GLOBAL, ip)))
  5712. +  {
  5713.      free(n);
  5714.      n = n2;
  5715.    }
  5716.  
  5717.    if (ttl) n->death_time = time(NULL)+ttl*3;
  5718.    n->ip = ip;
  5719. -  n->unique = unique;
  5720. +  n->nb_flags = nb_flags;
  5721.    n->source = source;
  5722.    
  5723.    if (!n2) add_name(n);
  5724.  
  5725. -  DEBUG(3,("Added host entry %s at %s ttl=%d unique=%s\n",
  5726. -       namestr(&n->name),inet_ntoa(ip),ttl,BOOLSTR(unique)));
  5727. +  DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
  5728. +            namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
  5729.  
  5730.    return(n);
  5731.  }
  5732.  
  5733.  
  5734.  /****************************************************************************
  5735. -  add a domain entry
  5736. +  remove an entry from the name list
  5737.    ****************************************************************************/
  5738. -static struct domain_record *add_domain_entry(char *name,struct in_addr ip)
  5739. +void remove_name_entry(char *name,int type)
  5740.  {
  5741. -  struct domain_record *d;
  5742. -
  5743. -  d = (struct domain_record *)malloc(sizeof(*d));
  5744. -
  5745. -  if (!d) return(NULL);
  5746. -
  5747. -  bzero((char *)d,sizeof(*d));
  5748. -
  5749. -  if (zero_ip(ip)) ip = bcast_ip;
  5750. -
  5751. -  StrnCpy(d->name,name,sizeof(d->name)-1);
  5752. -  d->bcast_ip = ip;
  5753. -
  5754. -  if (!PrimaryGroup[0] && ip_equal(bcast_ip,ip) && name[0] != '*') {
  5755. -    strcpy(PrimaryGroup,name);
  5756. -    strupper(PrimaryGroup);
  5757. -    DEBUG(3,("Setting primary group to %s (%s)\n",PrimaryGroup,inet_ntoa(ip)));
  5758. -  }
  5759. -
  5760. -  add_domain(d);
  5761. -
  5762. -  ip = *interpret_addr2("255.255.255.255");
  5763. -  if (name[0] != '*') add_host_entry(name,0x1e,False,0,SELF,ip);      
  5764. -
  5765. -  DEBUG(3,("Added domain entry %s at %s\n",
  5766. -       name,inet_ntoa(ip)));
  5767. -
  5768. -  return(d);
  5769. +  if (lp_wins_support())
  5770. +    {
  5771. +      /* we are a WINS server. */
  5772. +      remove_netbios_name(name,type,SELF,myip);
  5773. +    }
  5774. +  else
  5775. +    {
  5776. +      struct in_addr ip;
  5777. +      ip = ipzero;
  5778. +      
  5779. +      queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
  5780. +                 name, type, 0,
  5781. +                 False, True, ip);
  5782. +    }
  5783.  }
  5784.  
  5785. +
  5786.  /****************************************************************************
  5787. -  add a server entry
  5788. +  add an entry to the name list
  5789.    ****************************************************************************/
  5790. -struct server_record *add_server_entry(char *name,int servertype,
  5791. -                       int ttl,char *comment,BOOL replace)
  5792. +void add_name_entry(char *name,int type,int nb_flags)
  5793.  {
  5794. -  BOOL newentry=False;
  5795. -  struct server_record *s;
  5796. -
  5797. -  for (s = serverlist; s; s = s->next)
  5798. -    if (strequal(name,s->name)) break;
  5799. -
  5800. -  if (s && !replace) {
  5801. -    DEBUG(4,("Not replacing %s\n",name));
  5802. -    return(s);
  5803. -  }
  5804. -
  5805. -  updatedlists=True;
  5806. -
  5807. -  if (!s) {
  5808. -    newentry = True;
  5809. -    s = (struct server_record *)malloc(sizeof(*s));
  5810. -
  5811. -    if (!s) return(NULL);
  5812. +  /* always add our own entries */
  5813. +  add_netbios_entry(name,type,nb_flags,0,SELF,myip);
  5814.  
  5815. -    bzero((char *)s,sizeof(*s));
  5816. -  }
  5817. -
  5818. -  /* update the entry */
  5819. -  StrnCpy(s->name,name,sizeof(s->name)-1);
  5820. -  StrnCpy(s->comment,comment,sizeof(s->comment)-1);
  5821. -  s->servertype = servertype;
  5822. -  s->death_time = ttl?time(NULL)+ttl*3:0;
  5823. -  strupper(s->name);
  5824. -  if (s->servertype & SV_TYPE_DOMAIN_ENUM) strupper(s->comment);
  5825. -
  5826. -  if (!newentry) return(s);
  5827. -
  5828. -  add_server(s);
  5829. -
  5830. -  if (newentry) {
  5831. -    DEBUG(3,("Added server entry %s of type %x (%s)\n",
  5832. -         name,servertype,comment));
  5833. -  } else {
  5834. -    DEBUG(3,("Updated server entry %s of type %x (%s)\n",
  5835. -         name,servertype,comment));
  5836. -  }
  5837. -
  5838. -  return(s);
  5839. +  if (!lp_wins_support())
  5840. +    {
  5841. +      struct in_addr ip;
  5842. +      ip = ipzero;
  5843. +      
  5844. +      queue_netbios_pkt_wins(ClientNMB,NMB_REG,NAME_REGISTER,
  5845. +                 name, type, nb_flags,
  5846. +                 False, True, ip);
  5847. +    }
  5848.  }
  5849.  
  5850.  
  5851.  /****************************************************************************
  5852.    add the magic samba names, useful for finding samba servers
  5853.    **************************************************************************/
  5854. -static void add_my_names(void)
  5855. +void add_my_names(void)
  5856.  {
  5857.    struct in_addr ip;
  5858.  
  5859. -  ip = *interpret_addr2("0.0.0.0");
  5860. -
  5861. -  add_host_entry(myname,0x20,True,0,SELF,ip);
  5862. -  add_host_entry(myname,0x0,True,0,SELF,ip);
  5863. -  add_host_entry(myname,0x1f,True,0,SELF,ip); /* used for chat?? */
  5864. -  add_host_entry(myname,0x3,True,0,SELF,ip); /* used for winpopup */
  5865. -                        
  5866. -  if (!domainlist)
  5867. -    add_domain_entry(lp_workgroup(),bcast_ip);
  5868. -  add_server_entry(myname,
  5869. -           ServerType,
  5870. -           0,ServerComment,True);
  5871. -
  5872. -  add_host_entry("__SAMBA__",0x20,True,0,SELF,ip);
  5873. -  add_host_entry("__SAMBA__",0x0,True,0,SELF,ip);
  5874. -
  5875. -  if (lp_preferred_master()) {
  5876. -    DEBUG(3,("Preferred master startup\n"));
  5877. -    needelection = True;
  5878. -    ElectionCriterion |= (1<<3);
  5879. -  }
  5880. -
  5881. -  ElectionCriterion |= (lp_os_level() << 24);
  5882. -}
  5883. -
  5884. -
  5885. -/*******************************************************************
  5886. -  write out browse.dat
  5887. -  ******************************************************************/
  5888. -static void write_browse_list(void)
  5889. -{
  5890. -  struct server_record *s;
  5891. -  pstring fname,fnamenew;
  5892. -  FILE *f;
  5893. -  
  5894. -  updatecount++;
  5895. -
  5896. -  strcpy(fname,lp_lockdir());
  5897. -  trim_string(fname,NULL,"/");
  5898. -  strcat(fname,"/");
  5899. -  strcat(fname,SERVER_LIST);
  5900. -  strcpy(fnamenew,fname);
  5901. -  strcat(fnamenew,".");
  5902. +  ip = ipzero;
  5903.    
  5904. -  f = fopen(fnamenew,"w");
  5905. +  add_name_entry(myname,0x20,NB_ACTIVE);
  5906. +  add_name_entry(myname,0x03,NB_ACTIVE);
  5907. +  add_name_entry(myname,0x00,NB_ACTIVE);
  5908. +  add_name_entry(myname,0x1f,NB_ACTIVE);
  5909.    
  5910. -  if (!f) {
  5911. -    DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
  5912. -    return;
  5913. -  }
  5914. +  add_netbios_entry("*",0x0,NB_ACTIVE,0,SELF,ip);
  5915. +  add_netbios_entry("__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip);
  5916. +  add_netbios_entry("__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip);
  5917.    
  5918. -  for (s=serverlist; s ; s = s->next) {
  5919. -    /* don't list domains I don't have a master for */
  5920. -    if ((s->servertype & SV_TYPE_DOMAIN_ENUM) && !s->comment[0]) continue;
  5921. -    
  5922. -    fprintf(f,"\"%s\"\t%08x\t\"%s\"\n",s->name,s->servertype,s->comment);
  5923. +  if (lp_wins_support()) {
  5924. +    add_netbios_entry(inet_ntoa(myip),0x01,NB_ACTIVE,0,SELF,ip); /* nt as? */
  5925.    }
  5926. -  
  5927. -  
  5928. -  fclose(f);
  5929. -  chmod(fnamenew,0644);
  5930. -  /* unlink(fname); */
  5931. -  rename(fnamenew,fname);   
  5932. -  DEBUG(3,("Wrote browse list %s\n",fname));
  5933.  }
  5934.  
  5935.  /*******************************************************************
  5936. -  expire old names in the namelist and serverlist
  5937. +  refresh my own names
  5938.    ******************************************************************/
  5939. -static void expire_names(void)
  5940. +void refresh_my_names(time_t t)
  5941.  {
  5942. -  static time_t lastrun=0;
  5943. -  time_t t = time(NULL);
  5944. -  struct name_record *n;
  5945. -  struct name_record *next;
  5946. -  struct server_record *s;
  5947. -  struct server_record *nexts;
  5948. +  static time_t lasttime = 0;
  5949.  
  5950. -  if (!lastrun) lastrun = t;
  5951. -  if (t < lastrun + 5) return;
  5952. -  lastrun = t;
  5953. -
  5954. -  /* expire old names */
  5955. -  for (n = namelist; n; n = next) {
  5956. -    if (n->death_time && n->death_time < t) {
  5957. -      DEBUG(3,("Removing dead name %s\n",
  5958. -           namestr(&n->name)));
  5959. -      next = n->next;
  5960. -      if (n->prev) n->prev->next = n->next;
  5961. -      if (n->next) n->next->prev = n->prev;
  5962. -      if (namelist == n) namelist = n->next; 
  5963. -      free(n);
  5964. -    } else {
  5965. -      next = n->next;
  5966. -    }
  5967. -  }
  5968. +  if (t - lasttime < REFRESH_TIME) 
  5969. +    return;
  5970. +  lasttime = t;
  5971.  
  5972. -  /* expire old entries in the serverlist */
  5973. -  for (s = serverlist; s; s = nexts) {
  5974. -    if (s->death_time && s->death_time < t) {
  5975. -      DEBUG(3,("Removing dead server %s\n",s->name));
  5976. -      updatedlists = True;
  5977. -      nexts = s->next;
  5978. -      if (s->prev) s->prev->next = s->next;
  5979. -      if (s->next) s->next->prev = s->prev;
  5980. -      if (serverlist == s) serverlist = s->next; 
  5981. -      free(s);
  5982. -    } else {
  5983. -      nexts = s->next;
  5984. -    }
  5985. -  }
  5986. +  add_my_names();
  5987.  }
  5988.  
  5989. -
  5990.  /*******************************************************************
  5991. -  delete old names from the namelist
  5992. +  expires old names in the namelist
  5993.    ******************************************************************/
  5994. -static void housekeeping(void)
  5995. +void expire_names(time_t t)
  5996.  {
  5997. -  time_t t = time(NULL);
  5998. -
  5999. -  expire_names();
  6000. -
  6001. -  /* write out the browse.dat database for smbd to get */
  6002. -  if (updatedlists) {
  6003. -    write_browse_list();
  6004. -    updatedlists = False;
  6005. -  }
  6006. -
  6007. -  {
  6008. -    /* occasionally check to see if the master browser is around */
  6009. -    static time_t lastrun=0;
  6010. -    if (!lastrun) lastrun = t;
  6011. -    if (t < lastrun + 5*60) return;
  6012. -    lastrun = t;
  6013. -
  6014. -    if (!AM_MASTER && PrimaryGroup[0] &&
  6015. -    !name_query(ClientNMB,PrimaryGroup,0x1d,True,False,
  6016. -            bcast_ip,NULL,queue_packet)) {
  6017. -      DEBUG(2,("Forcing election on %s\n",PrimaryGroup));
  6018. -      needelection = True;
  6019. +  struct name_record *n;
  6020. +  struct name_record *next;
  6021. +  
  6022. +  /* expire old names */
  6023. +  for (n = namelist; n; n = next)
  6024. +    {
  6025. +      if (n->death_time && n->death_time < t)
  6026. +    {
  6027. +      DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
  6028. +      
  6029. +      next = n->next;
  6030. +      
  6031. +      if (n->prev) n->prev->next = n->next;
  6032. +      if (n->next) n->next->prev = n->prev;
  6033. +      
  6034. +      if (namelist == n) namelist = n->next; 
  6035. +      
  6036. +      free(n);
  6037. +    }
  6038. +      else
  6039. +    {
  6040. +      next = n->next;
  6041. +    }
  6042.      }
  6043. -  }
  6044.  }
  6045.  
  6046.  
  6047.  /****************************************************************************
  6048. -  reload the services file
  6049. -  **************************************************************************/
  6050. -BOOL reload_services(BOOL test)
  6051. +response for a reg release received
  6052. +**************************************************************************/
  6053. +void response_name_release(struct packet_struct *p)
  6054.  {
  6055. -  BOOL ret;
  6056. -  extern fstring remote_machine;
  6057. -
  6058. -  strcpy(remote_machine,"nmbd");
  6059. -
  6060. -  if (lp_loaded())
  6061. +  struct nmb_packet *nmb = &p->packet.nmb;
  6062. +  char *name = nmb->question.question_name.name;
  6063. +  int   type = nmb->question.question_name.name_type;
  6064. +  
  6065. +  DEBUG(4,("response name release received\n"));
  6066. +  
  6067. +  if (nmb->header.rcode == 0 && nmb->answers->rdata)
  6068.      {
  6069. -      pstring fname;
  6070. -      strcpy(fname,lp_configfile());
  6071. -      if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
  6072. +      struct in_addr found_ip;
  6073. +      putip((char*)&found_ip,&nmb->answers->rdata[2]);
  6074. +      
  6075. +      if (ip_equal(found_ip, myip))
  6076.      {
  6077. -      strcpy(servicesf,fname);
  6078. -      test = False;
  6079. +      remove_netbios_name(name,type,SELF,found_ip);
  6080.      }
  6081.      }
  6082. -
  6083. -  if (test && !lp_file_list_changed())
  6084. -    return(True);
  6085. -
  6086. -  ret = lp_load(servicesf,True);
  6087. -
  6088. -  /* perhaps the config filename is now set */
  6089. -  if (!test)
  6090. -    reload_services(True);
  6091. -
  6092. -  return(ret);
  6093. +  else
  6094. +    {
  6095. +      DEBUG(1,("name registration for %s rejected!\n",
  6096. +           namestr(&nmb->question.question_name)));
  6097. +    }
  6098.  }
  6099.  
  6100.  
  6101. -
  6102.  /****************************************************************************
  6103. -load a netbios hosts file
  6104. +reply to a name release
  6105.  ****************************************************************************/
  6106. -static void load_hosts_file(char *fname)
  6107. +void reply_name_release(struct packet_struct *p)
  6108.  {
  6109. -  FILE *f = fopen(fname,"r");
  6110. -  pstring line;
  6111. -  if (!f) {
  6112. -    DEBUG(2,("Can't open lmhosts file %s\n",fname));
  6113. -    return;
  6114. -  }
  6115. -
  6116. -  while (!feof(f))
  6117. +  struct nmb_packet *nmb = &p->packet.nmb;
  6118. +  struct in_addr ip;
  6119. +  int rcode=0;
  6120. +  int opcode = nmb->header.opcode;  
  6121. +  int nb_flags = nmb->additional->rdata[0];
  6122. +  BOOL bcast = nmb->header.nm_flags.bcast;
  6123. +  struct name_record *n;
  6124. +  char rdata[6];
  6125. +  
  6126. +  putip((char *)&ip,&nmb->additional->rdata[2]);  
  6127. +  
  6128. +  DEBUG(3,("Name release on name %s rcode=%d\n",
  6129. +       namestr(&nmb->question.question_name),rcode));
  6130. +  
  6131. +  n = find_name_search(&nmb->question.question_name, FIND_GLOBAL, ip);
  6132. +  
  6133. +  /* XXXX under what conditions should we reject the removal?? */
  6134. +  if (n && n->nb_flags == nb_flags && ip_equal(n->ip,ip))
  6135.      {
  6136. -      if (!fgets_slash(line,sizeof(pstring),f)) continue;
  6137. +      /* success = True;
  6138. +     rcode = 6; */
  6139.        
  6140. -      if (*line == '#') continue;
  6141. -
  6142. -      {
  6143. -    BOOL group=False;
  6144. -    string ip,name,flags,extra;
  6145. -    char *ptr;
  6146. -    int count = 0;
  6147. -    struct in_addr ipaddr;
  6148. -    enum name_source source = LMHOSTS;
  6149. -
  6150. -    *ip = *name = *flags = *extra = 0;
  6151. -
  6152. -    ptr = line;
  6153. -
  6154. -    if (next_token(&ptr,ip,NULL)) ++count;
  6155. -    if (next_token(&ptr,name,NULL)) ++count;
  6156. -    if (next_token(&ptr,flags,NULL)) ++count;
  6157. -    if (next_token(&ptr,extra,NULL)) ++count;
  6158. -
  6159. -    if (count <= 0) continue;
  6160. -
  6161. -    if (count > 0 && count < 2)
  6162. -      {
  6163. -        DEBUG(0,("Ill formed hosts line [%s]\n",line));        
  6164. -        continue;
  6165. -      }
  6166. -
  6167. -    if (strchr(flags,'G') || strchr(flags,'S'))
  6168. -      group = True;
  6169. -
  6170. -    if (strchr(flags,'M') && !group) {
  6171. -      source = SELF;
  6172. -      strcpy(myname,name);
  6173. -    }
  6174. -
  6175. -    ipaddr = *interpret_addr2(ip);
  6176. -
  6177. -    if (group) {
  6178. -      add_domain_entry(name,ipaddr);
  6179. -    } else {
  6180. -      add_host_entry(name,0x20,True,0,source,ipaddr);
  6181. -    }
  6182. -      }
  6183. +      remove_name(n);
  6184. +      n = NULL;
  6185.      }
  6186. -
  6187. -  fclose(f);
  6188. +  
  6189. +  if (bcast) return;
  6190. +  
  6191. +  /*if (success)*/
  6192. +  {
  6193. +    rdata[0] = nb_flags;
  6194. +    rdata[1] = 0;
  6195. +    putip(&rdata[2],(char *)&ip);
  6196. +  }
  6197. +  
  6198. +  /* Send a NAME RELEASE RESPONSE */
  6199. +  reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
  6200. +               &nmb->question.question_name,
  6201. +               nmb->question.question_type,
  6202. +               nmb->question.question_class,
  6203. +               0,
  6204. +               rdata, 6 /*success ? 6 : 0*/);
  6205. +  /* XXXX reject packet never tested: cannot tell what to do */
  6206.  }
  6207.  
  6208. -/*******************************************************************
  6209. -  check if 2 IPs are on the same net
  6210. -  we will assume the local netmask, although this could be wrong XXXX
  6211. -  ******************************************************************/
  6212. -static BOOL same_net(struct in_addr ip1,struct in_addr ip2)
  6213. -{
  6214. -  unsigned long net1,net2,nmask;
  6215. -
  6216. -  nmask = ntohl(Netmask.s_addr);
  6217. -  net1 = ntohl(ip1.s_addr);
  6218. -  net2 = ntohl(ip2.s_addr);
  6219. -        
  6220. -  return((net1 & nmask) == (net2 & nmask));
  6221. -}
  6222.  
  6223.  /****************************************************************************
  6224. -  send an election packet
  6225. -  **************************************************************************/
  6226. -static void send_election(char *group,uint32 criterion,int timeup,char *name)
  6227. +response for a reg request received
  6228. +**************************************************************************/
  6229. +void response_name_reg(struct packet_struct *p)
  6230.  {
  6231. -  pstring outbuf;
  6232. -  char *p;
  6233. -
  6234. -  DEBUG(2,("Sending election to %s for workgroup %s\n",
  6235. -       inet_ntoa(bcast_ip),group));       
  6236. -
  6237. -  bzero(outbuf,sizeof(outbuf));
  6238. -  p = outbuf;
  6239. -  CVAL(p,0) = 8; /* election */
  6240. -  p++;
  6241. -
  6242. -  CVAL(p,0) = ELECTION_VERSION;
  6243. -  SIVAL(p,1,criterion);
  6244. -  SIVAL(p,5,timeup*1000); /* ms - despite the spec */
  6245. -  p += 13;
  6246. -  strcpy(p,name);
  6247. -  strupper(p);
  6248. -  p = skip_string(p,1);
  6249. -
  6250. -  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6251. -              name,group,0,0x1e,bcast_ip,myip);
  6252. +  struct nmb_packet *nmb = &p->packet.nmb;
  6253. +  char *name = nmb->question.question_name.name;
  6254. +  int   type = nmb->question.question_name.name_type;
  6255. +  
  6256. +  DEBUG(4,("response name registration received!\n"));
  6257. +  
  6258. +  if (nmb->header.rcode == 0 && nmb->answers->rdata)
  6259. +    {
  6260. +      int nb_flags = nmb->answers->rdata[0];
  6261. +      struct in_addr found_ip;
  6262. +      int ttl = nmb->answers->ttl;
  6263. +      enum name_source source = REGISTER;
  6264. +      
  6265. +      putip((char*)&found_ip,&nmb->answers->rdata[2]);
  6266. +      
  6267. +      if (ip_equal(found_ip, myip)) source = SELF;
  6268. +      
  6269. +      add_netbios_entry(name,type,nb_flags,ttl,source,found_ip);
  6270. +    }
  6271. +  else
  6272. +    {
  6273. +      DEBUG(1,("name registration for %s rejected!\n",
  6274. +           namestr(&nmb->question.question_name)));
  6275. +    }
  6276.  }
  6277.  
  6278.  
  6279.  /****************************************************************************
  6280. -  send a backup list response
  6281. -  **************************************************************************/
  6282. -static void send_backup_list(char *name,int token,struct nmb_name *to,
  6283. -                 struct in_addr ip)
  6284. +reply to a reg request
  6285. +**************************************************************************/
  6286. +void reply_name_reg(struct packet_struct *p)
  6287.  {
  6288. -  pstring outbuf;
  6289. -  char *p;
  6290. -
  6291. -  DEBUG(2,("Sending backup list to %s for workgroup %s\n",
  6292. -       inet_ntoa(ip),PrimaryGroup));       
  6293. -
  6294. -  bzero(outbuf,sizeof(outbuf));
  6295. -  p = outbuf;
  6296. -  CVAL(p,0) = 10; /* backup list response */
  6297. -  p++;
  6298. -
  6299. -  CVAL(p,0) = 1; /* count */
  6300. -  SIVAL(p,1,token);
  6301. -  p += 5; 
  6302. -  strcpy(p,name);
  6303. -  strupper(p);
  6304. -  p = skip_string(p,1) + 1;
  6305. -
  6306. -  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6307. -              myname,to->name,0,to->name_type,ip,myip);
  6308. -}
  6309. -
  6310. -
  6311. -/*******************************************************************
  6312. -  become the master browser
  6313. -  ******************************************************************/
  6314. -static void become_master(void)
  6315. -{
  6316. -  uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_SERVER_UNIX;
  6317. -  DEBUG(2,("Becoming master for %s\n",PrimaryGroup));
  6318. -
  6319. -  ServerType |= SV_TYPE_MASTER_BROWSER;
  6320. -  ServerType |= SV_TYPE_BACKUP_BROWSER;
  6321. -  ElectionCriterion |= 0x5;
  6322. -
  6323. -  add_host_entry(PrimaryGroup,0x1d,True,0,SELF,myip);
  6324. -  add_host_entry(PrimaryGroup,0x0,False,0,SELF,myip);
  6325. -  add_host_entry(MSBROWSE,1,False,0,SELF,myip);
  6326. -
  6327. -  if (lp_domain_master()) {
  6328. -    add_host_entry(myname,0x1b,True,0,SELF,myip);
  6329. -    add_host_entry(PrimaryGroup,0x1b,True,0,SELF,myip);
  6330. -    add_host_entry(PrimaryGroup,0x1c,False,0,SELF,myip);
  6331. -    ServerType |= SV_TYPE_DOMAIN_MASTER;
  6332. -    if (lp_domain_logons()) {
  6333. -      ServerType |= SV_TYPE_DOMAIN_CTRL;
  6334. -      ServerType |= SV_TYPE_DOMAIN_MEMBER;
  6335. -      domain_type |= SV_TYPE_DOMAIN_CTRL;
  6336. -    }
  6337. -  }
  6338. -
  6339. -  add_server_entry(PrimaryGroup,domain_type,0,myname,True);
  6340. -  add_server_entry(myname,ServerType,0,ServerComment,True);
  6341. -
  6342. -  announce_request(PrimaryGroup);
  6343. -
  6344. -  needannounce = True;
  6345. -}
  6346. -
  6347. -
  6348. -/*******************************************************************
  6349. -  unbecome the master browser
  6350. -  ******************************************************************/
  6351. -static void become_nonmaster(void)
  6352. -{
  6353. -  struct name_record *n;
  6354. -  struct nmb_name nn;
  6355. -
  6356. -  DEBUG(2,("Becoming non-master for %s\n",PrimaryGroup));
  6357. -
  6358. -  ServerType &= ~SV_TYPE_MASTER_BROWSER;
  6359. -  ServerType &= ~SV_TYPE_DOMAIN_CTRL;
  6360. -  ServerType &= ~SV_TYPE_DOMAIN_MASTER;
  6361. -
  6362. -  ElectionCriterion &= ~0x4;
  6363. -
  6364. -  make_nmb_name(&nn,PrimaryGroup,0x1d,scope);
  6365. -  n = find_name(&nn);
  6366. -  if (n && n->source == SELF) remove_name(n);
  6367. -
  6368. -  make_nmb_name(&nn,PrimaryGroup,0x1b,scope);
  6369. -  n = find_name(&nn);
  6370. -  if (n && n->source == SELF) remove_name(n);
  6371. -
  6372. -  make_nmb_name(&nn,MSBROWSE,1,scope);
  6373. -  n = find_name(&nn);
  6374. -  if (n && n->source == SELF) remove_name(n);
  6375. -}
  6376. -
  6377. -
  6378. -/*******************************************************************
  6379. -  run the election
  6380. -  ******************************************************************/
  6381. -static void run_election(void)
  6382. -{
  6383. -  time_t t = time(NULL);
  6384. -  static time_t lastime = 0;
  6385. -
  6386. -  if (!PrimaryGroup[0] || !RunningElection) return;
  6387. -
  6388. -  /* send election packets once a second */
  6389. -  if (lastime &&
  6390. -      t-lastime <= 0) return;
  6391. -
  6392. -  lastime = t;
  6393. -
  6394. -  send_election(PrimaryGroup,ElectionCriterion,t-StartupTime,myname);
  6395. -
  6396. -  if (ElectionCount++ < 4) return;
  6397. -   
  6398. -  /* I won! now what :-) */
  6399. -  RunningElection = False;
  6400. -  DEBUG(2,(">>> Won election on %s <<<\n",PrimaryGroup));
  6401. -  become_master();
  6402. -}
  6403. -
  6404. -
  6405. -/****************************************************************************
  6406. -  construct a host announcement unicast
  6407. -  **************************************************************************/
  6408. -static void announce_host(struct domain_record *d,char *my_name,char *comment)
  6409. -{
  6410. -  time_t t = time(NULL);
  6411. -  pstring outbuf;
  6412. -  char *p;
  6413. -  char *namep;
  6414. -  char *stypep;
  6415. -  char *commentp;
  6416. -  uint32 stype = ServerType;
  6417. -
  6418. -  if (needannounce) {
  6419. -    /* drop back to a max 3 minute announce - this is to prevent a
  6420. -       single lost packet from stuffing things up for too long */
  6421. -    d->announce_interval = MIN(d->announce_interval,3*60);
  6422. -    d->lastannounce_time = t - (d->announce_interval+1);
  6423. -  }
  6424. -
  6425. -  /* announce every minute at first then progress to every 12 mins */
  6426. -  if (d->lastannounce_time && 
  6427. -      (t - d->lastannounce_time) < d->announce_interval)
  6428. -    return;
  6429. -
  6430. -  if (d->announce_interval < 12*60) d->announce_interval += 60;
  6431. -  d->lastannounce_time = t;
  6432. -
  6433. -  DEBUG(2,("Sending announcement to %s for workgroup %s\n",
  6434. -       inet_ntoa(d->bcast_ip),d->name));
  6435. -
  6436. -  if (!strequal(PrimaryGroup,d->name) ||
  6437. -      !ip_equal(bcast_ip,d->bcast_ip)) {
  6438. -    stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
  6439. -           SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
  6440. -           SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
  6441. -  }
  6442. -
  6443. -  if (!*comment) comment = "NoComment";
  6444. -  if (!*my_name) my_name = "NoName";
  6445. -
  6446. -  if (strlen(comment) > 43) comment[43] = 0;  
  6447. -
  6448. -  bzero(outbuf,sizeof(outbuf));
  6449. -  CVAL(outbuf,0) = 1; /* host announce */
  6450. -  p = outbuf+1;
  6451. -
  6452. -  CVAL(p,0) = updatecount;
  6453. -  SIVAL(p,1,d->announce_interval*1000); /* ms - despite the spec */
  6454. -  namep = p+5;
  6455. -  StrnCpy(p+5,my_name,16);
  6456. -  strupper(p+5);
  6457. -  CVAL(p,21) = 2; /* major version */
  6458. -  CVAL(p,22) = 2; /* minor version */
  6459. -  stypep = p+23;
  6460. -  SIVAL(p,23,stype);
  6461. -  SSVAL(p,27,0xaa55); /* browse signature */
  6462. -  SSVAL(p,29,1); /* browse version */
  6463. -  commentp = p+31;
  6464. -  strcpy(p+31,comment);
  6465. -  p += 31;
  6466. -  p = skip_string(p,1);
  6467. -
  6468. -  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6469. -              my_name,d->name,0,0x1d,d->bcast_ip,myip);
  6470. -
  6471. -  /* if I'm the master then I also need to do a local master and
  6472. -     domain announcement */
  6473. -
  6474. -  if (AM_MASTER &&
  6475. -      strequal(d->name,PrimaryGroup) &&
  6476. -      ip_equal(bcast_ip,d->bcast_ip)) {
  6477. -
  6478. -    /* do master announcements as well */
  6479. -    SIVAL(stypep,0,ServerType);
  6480. -
  6481. -    CVAL(outbuf,0) = 15; /* local master announce */
  6482. -    send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6483. -            my_name,PrimaryGroup,0,0x1e,d->bcast_ip,myip);
  6484. -
  6485. -    CVAL(outbuf,0) = 12; /* domain announce */
  6486. -    StrnCpy(namep,PrimaryGroup,15);
  6487. -    strupper(namep);
  6488. -    StrnCpy(commentp,myname,15);
  6489. -    strupper(commentp);
  6490. -    SIVAL(stypep,0,(unsigned)0x80000000);
  6491. -    p = commentp + strlen(commentp) + 1;
  6492. -
  6493. -    send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6494. -            my_name,MSBROWSE,0,1,d->bcast_ip,myip);
  6495. -  }
  6496. -}
  6497. -
  6498. -
  6499. -/****************************************************************************
  6500. -  send a announce request to the local net
  6501. -  **************************************************************************/
  6502. -static void announce_request(char *group)
  6503. -{
  6504. -  pstring outbuf;
  6505. -  char *p;
  6506. -
  6507. -  DEBUG(2,("Sending announce request to %s for workgroup %s\n",
  6508. -       inet_ntoa(bcast_ip),group));
  6509. -
  6510. -  bzero(outbuf,sizeof(outbuf));
  6511. -  p = outbuf;
  6512. -  CVAL(p,0) = 2; /* announce request */
  6513. -  p++;
  6514. -
  6515. -  CVAL(p,0) = 0; /* flags?? */
  6516. -  p++;
  6517. -  StrnCpy(p,myname,16);
  6518. -  strupper(p);
  6519. -  p = skip_string(p,1);
  6520. -
  6521. -  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6522. -              myname,group,0,0,bcast_ip,myip);
  6523. -}
  6524. -
  6525. -/****************************************************************************
  6526. -  announce myself as a master to the PDC
  6527. -  **************************************************************************/
  6528. -static void announce_master(char *group)
  6529. -{
  6530. -  static time_t last=0;
  6531. -  time_t t = time(NULL);
  6532. -  pstring outbuf;
  6533. -  char *p;
  6534. -  struct in_addr ip,pdc_ip;
  6535. -  fstring pdcname;
  6536. -  *pdcname = 0;
  6537. -
  6538. -  if (strequal(domain_controller(),myname)) return;
  6539. -
  6540. -  if (!AM_MASTER || (last && (t-last < 10*60))) return;
  6541. -  last = t;
  6542. -
  6543. -  ip = *interpret_addr2(domain_controller());
  6544. -
  6545. -  if (zero_ip(ip)) ip = bcast_ip;
  6546. -
  6547. -  if (!name_query(ClientNMB,PrimaryGroup,
  6548. -          0x1b,False,False,ip,&pdc_ip,queue_packet)) {
  6549. -    DEBUG(2,("Failed to find PDC at %s\n",domain_controller()));
  6550. -    return;
  6551. -  }
  6552. -
  6553. -  name_status(ClientNMB,PrimaryGroup,0x1b,False,
  6554. -          pdc_ip,NULL,pdcname,queue_packet);
  6555. -
  6556. -  if (!pdcname[0]) {
  6557. -    DEBUG(3,("Can't find netbios name of PDC at %s\n",inet_ntoa(pdc_ip)));
  6558. -  } else {
  6559. -    sync_browse_lists(pdcname,0x20,myname,PrimaryGroup,pdc_ip);
  6560. -  }
  6561. -
  6562. -
  6563. -  DEBUG(2,("Sending master announce to %s for workgroup %s\n",
  6564. -       inet_ntoa(pdc_ip),group));
  6565. -
  6566. -  bzero(outbuf,sizeof(outbuf));
  6567. -  p = outbuf;
  6568. -  CVAL(p,0) = 13; /* announce request */
  6569. -  p++;
  6570. -
  6571. -  StrnCpy(p,myname,16);
  6572. -  strupper(p);
  6573. -  p = skip_string(p,1);
  6574. -
  6575. -  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  6576. -              myname,PrimaryGroup,0x1b,0,pdc_ip,myip);
  6577. -}
  6578. -
  6579. -
  6580. -/*******************************************************************
  6581. -  am I listening on a name. Should check name_type as well 
  6582. -
  6583. -  This is primarily used to prevent us gathering server lists from
  6584. -  other workgroups we aren't a part of
  6585. -  ******************************************************************/
  6586. -static BOOL listening(struct nmb_name *n)
  6587. -{
  6588. -  if (!strequal(n->scope,scope)) return(False);
  6589. -
  6590. -  if (strequal(n->name,myname) ||
  6591. -      strequal(n->name,PrimaryGroup) ||
  6592. -      strequal(n->name,MSBROWSE))
  6593. -    return(True);
  6594. -
  6595. -  return(False);
  6596. -}
  6597. -
  6598. -
  6599. -/*******************************************************************
  6600. -  process a domain announcement frame
  6601. -
  6602. -  Announce frames come in 3 types. Servers send host announcements
  6603. -  (command=1) to let the master browswer know they are
  6604. -  available. Master browsers send local master announcements
  6605. -  (command=15) to let other masters and backups that they are the
  6606. -  master. They also send domain announcements (command=12) to register
  6607. -  the domain
  6608. -
  6609. -  The comment field of domain announcements contains the master
  6610. -  browser name. The servertype is used by NetServerEnum to select
  6611. -  resources. We just have to pass it to smbd (via browser.dat) and let
  6612. -  the client choose using bit masks.
  6613. -  ******************************************************************/
  6614. -static void process_announce(struct packet_struct *p,int command,char *buf)
  6615. -{
  6616. -  struct dgram_packet *dgram = &p->packet.dgram;
  6617. -  int update_count = CVAL(buf,0);
  6618. -  int ttl = IVAL(buf,1)/1000;
  6619. -  char *name = buf+5;
  6620. -  int osmajor=CVAL(buf,21);
  6621. -  int osminor=CVAL(buf,22);
  6622. -  uint32 servertype = IVAL(buf,23);
  6623. -  char *comment = buf+31;
  6624. -
  6625. -  name[15] = 0;  
  6626. -  comment[43] = 0;
  6627. +  struct nmb_packet *nmb = &p->packet.nmb;
  6628. +  struct nmb_name *question = &nmb->question.question_name;
  6629. +  char *qname = nmb->question.question_name.name;
  6630. +  int name_type = nmb->question.question_name.name_type;
  6631.    
  6632. -  DEBUG(3,("Announce(%d) %s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
  6633. -       command,name,update_count,ttl,osmajor,osminor,
  6634. -       servertype,comment));
  6635. -
  6636. -  if (strequal(dgram->source_name.name,myname)) return;
  6637. -
  6638. -  if (!listening(&dgram->dest_name)) return;
  6639. -
  6640. -  ttl = GET_TTL(ttl);
  6641. -
  6642. -  /* add them to our browse list */
  6643. -  add_server_entry(name,servertype,ttl,comment,True);
  6644. -
  6645. -}
  6646. -
  6647. -/*******************************************************************
  6648. -  process a master announcement frame
  6649. -  ******************************************************************/
  6650. -static void process_master_announce(struct packet_struct *p,char *buf)
  6651. -{
  6652. -  struct dgram_packet *dgram = &p->packet.dgram;
  6653. -  char *name = buf;
  6654. -
  6655. -  name[15] = 0;
  6656. +  BOOL bcast = nmb->header.nm_flags.bcast;
  6657.    
  6658. -  DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
  6659. -
  6660. -  if (strequal(dgram->source_name.name,myname)) return;
  6661. -
  6662. -  if (!AM_MASTER || !listening(&dgram->dest_name)) return;
  6663. -
  6664. -  /* merge browse lists with them */
  6665. -  if (lp_domain_master())
  6666. -    sync_browse_lists(name,0x20,myname,PrimaryGroup,p->ip);
  6667. -}
  6668. -
  6669. -
  6670. -/*******************************************************************
  6671. -  process a backup list request
  6672. -
  6673. -  A client send a backup list request to ask for a list of servers on
  6674. -  the net that maintain server lists for a domain. A server is then
  6675. -  chosen from this list to send NetServerEnum commands to to list
  6676. -  available servers.
  6677. -
  6678. -  Currently samba only sends back one name in the backup list, its
  6679. -  wn. For larger nets we'll have to add backups and send "become
  6680. -  backup" requests occasionally.
  6681. -  ******************************************************************/
  6682. -static void process_backup_list(struct packet_struct *p,char *buf)
  6683. -{
  6684. -  struct dgram_packet *dgram = &p->packet.dgram;
  6685. -  int count = CVAL(buf,0);
  6686. -  int token = IVAL(buf,1);
  6687. +  int ttl = GET_TTL(nmb->additional->ttl);
  6688. +  int nb_flags = nmb->additional->rdata[0];
  6689. +  BOOL group = (nb_flags&0x80);
  6690. +  int rcode = 0;  
  6691. +  int opcode = nmb->header.opcode;  
  6692. +  struct name_record *n = NULL;
  6693. +  int success = True;
  6694. +  char rdata[6];
  6695. +  struct in_addr ip, from_ip;
  6696.    
  6697. -  DEBUG(3,("Backup request to %s token=%d\n",
  6698. -       namestr(&dgram->dest_name),
  6699. -       token));
  6700. -
  6701. -  if (strequal(dgram->source_name.name,myname)) return;
  6702. -
  6703. -  if (count <= 0) return;
  6704. -
  6705. -  if (!AM_MASTER || 
  6706. -      !strequal(PrimaryGroup,dgram->dest_name.name))
  6707. -    return;
  6708. -
  6709. -  if (!listening(&dgram->dest_name)) return;
  6710. -
  6711. -  send_backup_list(myname,token,
  6712. -           &dgram->source_name,
  6713. -           p->ip);
  6714. -}
  6715. -
  6716. -
  6717. -/*******************************************************************
  6718. -  work out if I win an election
  6719. -  ******************************************************************/
  6720. -static BOOL win_election(int version,uint32 criterion,int timeup,char *name)
  6721. -{  
  6722. -  time_t t = time(NULL);
  6723. -  uint32 mycriterion;
  6724. -  if (version > ELECTION_VERSION) return(False);
  6725. -  if (version < ELECTION_VERSION) return(True);
  6726. +  putip((char *)&from_ip,&nmb->additional->rdata[2]);
  6727. +  ip = from_ip;
  6728.    
  6729. -  mycriterion = ElectionCriterion;
  6730. -
  6731. -  if (criterion > mycriterion) return(False);
  6732. -  if (criterion < mycriterion) return(True);
  6733. -
  6734. -  if (timeup > (t - StartupTime)) return(False);
  6735. -  if (timeup < (t - StartupTime)) return(True);
  6736. -
  6737. -  if (strcasecmp(myname,name) > 0) return(False);
  6738. -  
  6739. -  return(True);
  6740. -}
  6741. -
  6742. -
  6743. -/*******************************************************************
  6744. -  process a election packet
  6745. -
  6746. -  An election dynamically decides who will be the master. 
  6747. -  ******************************************************************/
  6748. -static void process_election(struct packet_struct *p,char *buf)
  6749. -{
  6750. -  struct dgram_packet *dgram = &p->packet.dgram;
  6751. -  int version = CVAL(buf,0);
  6752. -  uint32 criterion = IVAL(buf,1);
  6753. -  int timeup = IVAL(buf,5)/1000;
  6754. -  char *name = buf+13;
  6755. -
  6756. -  name[15] = 0;  
  6757. +  DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
  6758. +       namestr(question),inet_ntoa(ip),rcode));
  6759.    
  6760. -  DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
  6761. -       name,version,criterion,timeup));
  6762. -
  6763. -  if (strequal(dgram->source_name.name,myname)) return;
  6764. -
  6765. -  if (!listening(&dgram->dest_name)) return;
  6766. -
  6767. -  if (win_election(version,criterion,timeup,name)) {
  6768. -    if (!RunningElection) {
  6769. -      needelection = True;
  6770. -      ElectionCount=0;
  6771. -    }
  6772. -  } else {
  6773. -    needelection = False;
  6774. -    if (RunningElection) {
  6775. -      RunningElection = False;
  6776. -      DEBUG(3,(">>> Lost election on %s <<<\n",PrimaryGroup));
  6777. -
  6778. -      /* if we are the master then remove our masterly names */
  6779. -      if (AM_MASTER)
  6780. -    become_nonmaster();
  6781. +  if (group)
  6782. +    {
  6783. +      /* apparently we should return 255.255.255.255 for group queries
  6784. +     (email from MS) */
  6785. +      ip = *interpret_addr2("255.255.255.255");
  6786.      }
  6787. -  }
  6788. -}
  6789. -
  6790. -
  6791. -/*******************************************************************
  6792. -  process a announcement request
  6793. -
  6794. -  clients send these when they want everyone to send an announcement
  6795. -  immediately. This can cause quite a storm of packets!
  6796. -  ******************************************************************/
  6797. -static void process_announce_request(struct packet_struct *p,char *buf)
  6798. -{
  6799. -  struct dgram_packet *dgram = &p->packet.dgram;
  6800. -  int flags = CVAL(buf,0);
  6801. -  char *name = buf+1;
  6802. -
  6803. -  name[15] = 0;
  6804. -
  6805. -  DEBUG(3,("Announce request from %s flags=0x%X\n",name,flags));
  6806. -
  6807. -  if (strequal(dgram->source_name.name,myname)) return;
  6808. -
  6809. -  needannounce = True;
  6810. -}
  6811. -
  6812. -
  6813. -/****************************************************************************
  6814. -process a browse frame
  6815. -****************************************************************************/
  6816. -static void process_browse_packet(struct packet_struct *p,char *buf,int len)
  6817. -{
  6818. -  int command = CVAL(buf,0);
  6819. -  switch (command) 
  6820. +  
  6821. +  /* see if the name already exists */
  6822. +  n = find_name_search(question, FIND_GLOBAL, from_ip);
  6823. +  
  6824. +  if (n)
  6825.      {
  6826. -    case 1: /* host announce */
  6827. -    case 12: /* domain announce */
  6828. -    case 15: /* local master announce */
  6829. -      process_announce(p,command,buf+1);
  6830. -      break;
  6831. -
  6832. -    case 2: /* announce request */
  6833. -      process_announce_request(p,buf+1);
  6834. -      break;
  6835. -
  6836. -    case 8: /* election */
  6837. -      process_election(p,buf+1);
  6838. -      break;
  6839. -
  6840. -    case 9: /* get backup list */
  6841. -      process_backup_list(p,buf+1);
  6842. -      break;
  6843. -
  6844. -    case 13: /* master announcement */
  6845. -      process_master_announce(p,buf+1);
  6846. -      break;
  6847. +      if (!group && !ip_equal(ip,n->ip) && question->name_type != 0x3)
  6848. +    {
  6849. +      if (n->source == SELF)
  6850. +        {
  6851. +          rcode = 6;
  6852. +          success = False;
  6853. +        }
  6854. +      else
  6855. +        {
  6856. +          n->ip = ip;
  6857. +          n->death_time = ttl?p->timestamp+ttl*3:0;
  6858. +          DEBUG(3,("%s changed owner to %s\n",
  6859. +               namestr(&n->name),inet_ntoa(n->ip)));
  6860. +        }
  6861. +    }
  6862. +      else
  6863. +    {
  6864. +      /* refresh the name */
  6865. +      if (n->source != SELF)
  6866. +        {
  6867. +          n->death_time = ttl?p->timestamp + ttl*3:0;
  6868. +        }
  6869. +    }
  6870.      }
  6871. -}
  6872. -
  6873. -
  6874. -/****************************************************************************
  6875. -  process a domain logon packet
  6876. -  **************************************************************************/
  6877. -static void process_logon_packet(struct packet_struct *p,char *buf,int len)
  6878. -{
  6879. -  char *logname,*q;
  6880. -  pstring outbuf;
  6881. -  struct dgram_packet *dgram = &p->packet.dgram;
  6882. -  int code;
  6883. -
  6884. -  if (!lp_domain_logons()) {
  6885. -    DEBUG(3,("No domain logons\n"));
  6886. -    return;
  6887. -  }
  6888. -  if (!listening(&dgram->dest_name)) {
  6889. -    DEBUG(4,("Not listening to that domain\n"));
  6890. -    return;
  6891. -  }
  6892. -
  6893. -  q = outbuf;
  6894. -  bzero(outbuf,sizeof(outbuf));
  6895. -
  6896. -  code = SVAL(buf,0);
  6897. -  switch (code) {
  6898. -  case 0:    
  6899. -    {
  6900. -      char *machine = buf+2;
  6901. -      char *user = skip_string(machine,1);
  6902. -      logname = skip_string(user,1);
  6903. -
  6904. -      SSVAL(q,0,6);
  6905. -      q += 2;
  6906. -      strcpy(q,"\\\\");
  6907. -      q += 2;
  6908. -      StrnCpy(q,myname,16);
  6909. -      strupper(q);
  6910. -      q = skip_string(q,1);
  6911. -      SSVAL(q,0,0xFFFF);
  6912. -      q += 2;
  6913. -
  6914. -      DEBUG(3,("Domain login request from %s(%s) user=%s\n",
  6915. -           machine,inet_ntoa(p->ip),user));
  6916. -    }
  6917. -    break;
  6918. -  case 7:    
  6919. -    {
  6920. -      char *machine = buf+2;
  6921. -      logname = skip_string(machine,1);
  6922. -
  6923. -      SSVAL(q,0,0xc);
  6924. -      q += 2;
  6925. -      StrnCpy(q,domain_controller(),16);
  6926. -      strupper(q);
  6927. -      q = skip_string(q,1);
  6928. -      q += PutUniCode(q,domain_controller());
  6929. -      q += PutUniCode(q,dgram->dest_name.name);
  6930. -      SSVAL(q,0,0xFFFF);
  6931. -      q += 2;
  6932. -
  6933. -      DEBUG(3,("GETDC request from %s(%s)\n",
  6934. -           machine,inet_ntoa(p->ip)));
  6935. -    }
  6936. -    break;
  6937. -  default:
  6938. -    DEBUG(3,("Unknown domain request %d\n",code));
  6939. -    return;
  6940. -  }
  6941. -
  6942. -
  6943. -  send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
  6944. -              myname,&dgram->source_name.name[0],0,0,p->ip,myip);  
  6945. -}
  6946. -
  6947. -/****************************************************************************
  6948. -process udp 138 datagrams
  6949. -****************************************************************************/
  6950. -static void process_dgram(struct packet_struct *p)
  6951. -{
  6952. -  char *buf;
  6953. -  char *buf2;
  6954. -  int len;
  6955. -  struct dgram_packet *dgram = &p->packet.dgram;
  6956. -
  6957. -  if (dgram->header.msg_type != 0x10 &&
  6958. -      dgram->header.msg_type != 0x11 &&
  6959. -      dgram->header.msg_type != 0x12) {
  6960. -    /* don't process error packets etc yet */
  6961. -    return;
  6962. -  }
  6963. -
  6964. -  buf = &dgram->data[0];
  6965. -  buf -= 4; /* XXXX for the pseudo tcp length - 
  6966. -           someday I need to get rid of this */
  6967. -
  6968. -  if (CVAL(buf,smb_com) != SMBtrans) return;
  6969. -
  6970. -  len = SVAL(buf,smb_vwv11);
  6971. -  buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
  6972. -
  6973. -  DEBUG(3,("datagram from %s to %s for %s of type %d len=%d\n",
  6974. -       namestr(&dgram->source_name),namestr(&dgram->dest_name),
  6975. -       smb_buf(buf),CVAL(buf2,0),len));
  6976. -
  6977. -  if (len <= 0) return;
  6978. -
  6979. -  if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE")) {
  6980. -    process_browse_packet(p,buf2,len);
  6981. -  } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
  6982. -    process_logon_packet(p,buf2,len);
  6983. -  }
  6984. -
  6985. -}
  6986. -
  6987. -/*******************************************************************
  6988. -  find a workgroup using the specified broadcast
  6989. -  ******************************************************************/
  6990. -static BOOL find_workgroup(char *name,struct in_addr ip)
  6991. -{
  6992. -  fstring name1;
  6993. -  BOOL ret;
  6994. -  struct in_addr ipout;
  6995. -
  6996. -  strcpy(name1,MSBROWSE);
  6997. -
  6998. -  ret = name_query(ClientNMB,name1,0x1,True,False,ip,&ipout,queue_packet);
  6999. -  if (!ret) return(False);
  7000. -
  7001. -  name_status(ClientNMB,name1,0x1,False,ipout,name,NULL,queue_packet);
  7002. -
  7003. -  if (name[0] != '*') {
  7004. -    DEBUG(2,("Found workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
  7005. -  } else {
  7006. -    DEBUG(3,("Failed to find workgroup %s on broadcast %s\n",name,inet_ntoa(ip)));
  7007. -  }
  7008. -  return(name[0] != '*');
  7009. -}
  7010. -
  7011. -
  7012. -/****************************************************************************
  7013. -  a hook for announce handling - called every minute
  7014. -  **************************************************************************/
  7015. -static void do_announcements(void)
  7016. -{
  7017. -  struct domain_record *d;
  7018. -
  7019. -  for (d = domainlist; d; d = d->next) {
  7020. -    /* if the ip address is 0 then set to the broadcast */
  7021. -    if (zero_ip(d->bcast_ip)) d->bcast_ip = bcast_ip;
  7022. -
  7023. -    /* if the workgroup is '*' then find a workgroup to be part of */
  7024. -    if (d->name[0] == '*') {
  7025. -      if (!find_workgroup(d->name,d->bcast_ip)) continue;
  7026. -      add_host_entry(d->name,0x1e,False,0,SELF,
  7027. -             *interpret_addr2("255.255.255.255"));
  7028. -      if (!PrimaryGroup[0] && ip_equal(bcast_ip,d->bcast_ip)) {
  7029. -    strcpy(PrimaryGroup,d->name);
  7030. -    strupper(PrimaryGroup);
  7031. -      }
  7032. +  else
  7033. +    {
  7034. +      /* add the name to our subnet/name database */
  7035. +      n = add_netbios_entry(qname,name_type,nb_flags,ttl,REGISTER,ip);
  7036.      }
  7037. -
  7038. -    announce_host(d,myname,ServerComment);
  7039. -  }
  7040. -
  7041. -  /* if I have a domain controller then announce to it */
  7042. -  if (AM_MASTER)
  7043. -    announce_master(PrimaryGroup);
  7044. -
  7045. -  needannounce=False;
  7046. -}
  7047. -
  7048. -/*******************************************************************
  7049. -  check if someone still owns a name
  7050. -  ******************************************************************/
  7051. -static BOOL confirm_name(struct name_record *n)
  7052. -{
  7053. -  struct in_addr ipout;
  7054. -  BOOL ret = name_query(ClientNMB,n->name.name,
  7055. -            n->name.name_type,False,
  7056. -            False,n->ip,&ipout,queue_packet);
  7057. -  return(ret && ip_equal(ipout,n->ip));
  7058. -}
  7059. -
  7060. -/****************************************************************************
  7061. -reply to a name release
  7062. -****************************************************************************/
  7063. -static void reply_name_release(struct packet_struct *p)
  7064. -{
  7065. -  struct nmb_packet *nmb = &p->packet.nmb;
  7066. -  struct packet_struct p2;
  7067. -  struct nmb_packet *nmb2;
  7068. -  struct res_rec answer_rec;
  7069. -  struct in_addr ip;
  7070. -  int rcode=0;
  7071. -  int nb_flags = nmb->additional->rdata[0];
  7072. -  BOOL bcast = nmb->header.nm_flags.bcast;
  7073.    
  7074. -
  7075. -  putip((char *)&ip,&nmb->additional->rdata[2]);  
  7076. -
  7077. -  {
  7078. -    struct name_record *n = find_name(&nmb->question.question_name);
  7079. -    if (n && n->unique && n->source == REGISTER &&
  7080. -    ip_equal(ip,n->ip)) {
  7081. -      remove_name(n); n = NULL;
  7082. -    }
  7083. -
  7084. -    /* XXXX under what conditions should we reject the removal?? */
  7085. -  }
  7086. -
  7087. -  DEBUG(3,("Name release on name %s rcode=%d\n",
  7088. -       namestr(&nmb->question.question_name),rcode));
  7089. -
  7090.    if (bcast) return;
  7091. -
  7092. -  /* Send a NAME RELEASE RESPONSE */
  7093. -  p2 = *p;
  7094. -  nmb2 = &p2.packet.nmb;
  7095. -
  7096. -  nmb2->header.response = True;
  7097. -  nmb2->header.nm_flags.bcast = False;
  7098. -  nmb2->header.nm_flags.recursion_available = CanRecurse;
  7099. -  nmb2->header.nm_flags.trunc = False;
  7100. -  nmb2->header.nm_flags.authoritative = True; 
  7101. -  nmb2->header.qdcount = 0;
  7102. -  nmb2->header.ancount = 1;
  7103. -  nmb2->header.nscount = 0;
  7104. -  nmb2->header.arcount = 0;
  7105. -  nmb2->header.rcode = rcode;
  7106. -
  7107. -  nmb2->answers = &answer_rec;
  7108. -  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  7109. -  
  7110. -  nmb2->answers->rr_name = nmb->question.question_name;
  7111. -  nmb2->answers->rr_type = nmb->question.question_type;
  7112. -  nmb2->answers->rr_class = nmb->question.question_class;
  7113. -  nmb2->answers->ttl = 0; 
  7114. -  nmb2->answers->rdlength = 6;
  7115. -  nmb2->answers->rdata[0] = nb_flags;
  7116. -  putip(&nmb2->answers->rdata[2],(char *)&ip);
  7117. -
  7118. -  send_packet(&p2);
  7119. -}
  7120. -
  7121. -/****************************************************************************
  7122. -  reply to a reg request
  7123. -  **************************************************************************/
  7124. -static void reply_name_reg(struct packet_struct *p)
  7125. -{
  7126. -  struct nmb_packet *nmb = &p->packet.nmb;
  7127. -  char *qname = nmb->question.question_name.name;
  7128. -  BOOL wildcard = (qname[0] == '*'); 
  7129. -  BOOL bcast = nmb->header.nm_flags.bcast;
  7130. -  int ttl = GET_TTL(nmb->additional->ttl);
  7131. -  int name_type = nmb->question.question_name.name_type;
  7132. -  int nb_flags = nmb->additional->rdata[0];
  7133. -  struct packet_struct p2;
  7134. -  struct nmb_packet *nmb2;
  7135. -  struct res_rec answer_rec;
  7136. -  struct in_addr ip;
  7137. -  BOOL group = (nb_flags&0x80)?True:False;
  7138. -  int rcode = 0;  
  7139. -
  7140. -  if (wildcard) return;
  7141. -
  7142. -  putip((char *)&ip,&nmb->additional->rdata[2]);
  7143. -
  7144. -  if (group) {
  7145. -    /* apparently we should return 255.255.255.255 for group queries (email from MS) */
  7146. -    ip = *interpret_addr2("255.255.255.255");
  7147. -  }
  7148. -
  7149. +  
  7150. +  update_from_reg(nmb->question.question_name.name,
  7151. +          nmb->question.question_name.name_type, from_ip);
  7152. +  
  7153. +  /* XXXX don't know how to reject a name register: stick info in anyway
  7154. +     and guess that it doesn't matter if info is there! */
  7155. +  /*if (success)*/
  7156.    {
  7157. -    struct name_record *n = find_name(&nmb->question.question_name);
  7158. -
  7159. -    if (n) {
  7160. -      if (!group && !ip_equal(ip,n->ip)) {
  7161. -    /* check if the previous owner still wants it, 
  7162. -       if so reject the registration, otherwise change the owner 
  7163. -       and refresh */
  7164. -    if (n->source != REGISTER || confirm_name(n)) {
  7165. -      rcode = 6;
  7166. -    } else {
  7167. -      n->ip = ip;
  7168. -      n->death_time = ttl?p->timestamp+ttl*3:0;
  7169. -      DEBUG(3,("%s changed owner to %s\n",
  7170. -           namestr(&n->name),inet_ntoa(n->ip)));
  7171. -    }
  7172. -      } else {
  7173. -    /* refresh the name */
  7174. -    if (n->source != SELF)
  7175. -      n->death_time = ttl?p->timestamp + ttl*3:0;
  7176. -      }
  7177. -    } else {
  7178. -      /* add the name to our database */
  7179. -      n = add_host_entry(qname,name_type,!group,ttl,REGISTER,ip);
  7180. -    }
  7181. +    rdata[0] = nb_flags;
  7182. +    rdata[1] = 0;
  7183. +    putip(&rdata[2],(char *)&ip);
  7184.    }
  7185. -
  7186. -  if (bcast) return;
  7187. -
  7188. -  DEBUG(3,("Name registration for name %s at %s rcode=%d\n",
  7189. -       namestr(&nmb->question.question_name),
  7190. -       inet_ntoa(ip),rcode));
  7191. -
  7192. +  
  7193.    /* Send a NAME REGISTRATION RESPONSE */
  7194. -  /* a lot of fields get copied from the query. This gives us the IP
  7195. -     and port the reply will be sent to etc */
  7196. -  p2 = *p;
  7197. -  nmb2 = &p2.packet.nmb;
  7198. -
  7199. -  nmb2->header.opcode = 5; 
  7200. -  nmb2->header.response = True;
  7201. -  nmb2->header.nm_flags.bcast = False;
  7202. -  nmb2->header.nm_flags.recursion_available = CanRecurse;
  7203. -  nmb2->header.nm_flags.trunc = False;
  7204. -  nmb2->header.nm_flags.authoritative = True; 
  7205. -  nmb2->header.qdcount = 0;
  7206. -  nmb2->header.ancount = 1;
  7207. -  nmb2->header.nscount = 0;
  7208. -  nmb2->header.arcount = 0;
  7209. -  nmb2->header.rcode = rcode;
  7210. -
  7211. -  nmb2->answers = &answer_rec;
  7212. -  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  7213. -  
  7214. -  nmb2->answers->rr_name = nmb->question.question_name;
  7215. -  nmb2->answers->rr_type = nmb->question.question_type;
  7216. -  nmb2->answers->rr_class = nmb->question.question_class;
  7217. -
  7218. -  nmb2->answers->ttl = ttl; 
  7219. -  nmb2->answers->rdlength = 6;
  7220. -  nmb2->answers->rdata[0] = nb_flags;
  7221. -  putip(&nmb2->answers->rdata[2],(char *)&ip);
  7222. -
  7223. -  send_packet(&p2);  
  7224. +  reply_netbios_packet(p,nmb->header.name_trn_id,rcode,opcode,
  7225. +               &nmb->question.question_name,
  7226. +               nmb->question.question_type,
  7227. +               nmb->question.question_class,
  7228. +               ttl,
  7229. +               rdata, 6 /*success ? 6 : 0*/);
  7230.  }
  7231.  
  7232.  
  7233.  /****************************************************************************
  7234.  reply to a name status query
  7235.  ****************************************************************************/
  7236. -static void reply_name_status(struct packet_struct *p)
  7237. +void reply_name_status(struct packet_struct *p)
  7238.  {
  7239.    struct nmb_packet *nmb = &p->packet.nmb;
  7240. -  char *qname = nmb->question.question_name.name;
  7241. +  char *qname   = nmb->question.question_name.name;
  7242. +  int ques_type = nmb->question.question_name.name_type;
  7243.    BOOL wildcard = (qname[0] == '*'); 
  7244. -  struct packet_struct p2;
  7245. -  struct nmb_packet *nmb2;
  7246. -  struct res_rec answer_rec;
  7247. -  char *buf;
  7248. -  int count;
  7249. -  int rcode = 0;
  7250. -  struct name_record *n = find_name(&nmb->question.question_name);
  7251. -
  7252. -  DEBUG(3,("Name status for name %s\n",
  7253. -       namestr(&nmb->question.question_name)));
  7254. -
  7255. -  if (!wildcard && (!n || n->source != SELF)) 
  7256. -    return;
  7257. -
  7258. -  /* Send a POSITIVE NAME STATUS RESPONSE */
  7259. -  /* a lot of fields get copied from the query. This gives us the IP
  7260. -     and port the reply will be sent to etc */
  7261. -  p2 = *p;
  7262. -  nmb2 = &p2.packet.nmb;
  7263. -
  7264. -  nmb2->header.response = True;
  7265. -  nmb2->header.nm_flags.bcast = False;
  7266. -  nmb2->header.nm_flags.recursion_available = CanRecurse;
  7267. -  nmb2->header.nm_flags.trunc = False;
  7268. -  nmb2->header.nm_flags.authoritative = True; /* WfWg ignores 
  7269. -                         non-authoritative answers */
  7270. -  nmb2->header.qdcount = 0;
  7271. -  nmb2->header.ancount = 1;
  7272. -  nmb2->header.nscount = 0;
  7273. -  nmb2->header.arcount = 0;
  7274. -  nmb2->header.rcode = rcode;
  7275. -
  7276. -  nmb2->answers = &answer_rec;
  7277. -  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  7278. -  
  7279. -
  7280. -  nmb2->answers->rr_name = nmb->question.question_name;
  7281. -  nmb2->answers->rr_type = nmb->question.question_type;
  7282. -  nmb2->answers->rr_class = nmb->question.question_class;
  7283. -  nmb2->answers->ttl = 0; 
  7284. -
  7285. -  for (count=0, n = namelist ; n; n = n->next) {
  7286. -    if (n->source != SELF) continue;
  7287. -    count++;
  7288. -  }
  7289. -
  7290. -  count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
  7291. -                how many will fit */
  7292. -
  7293. +  char rdata[MAX_DGRAM_SIZE];
  7294. +  char *countptr, *buf;
  7295. +  int count, names_added;
  7296. +  struct name_record *n;
  7297. +  
  7298. +  DEBUG(3,("Name status for name %s %s\n",
  7299. +       namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
  7300. +  
  7301. +  /* find a name: if it's a wildcard, search the entire database.
  7302. +     if not, search for source SELF names only */
  7303. +  n = find_name_search(&nmb->question.question_name,
  7304. +               wildcard ? FIND_GLOBAL : FIND_SELF, p->ip);
  7305. +  
  7306. +  if (!wildcard && (!n || n->source != SELF)) return;
  7307. +  
  7308. +  for (count=0, n = namelist ; n; n = n->next)
  7309. +    {
  7310. +      int name_type = n->name.name_type;
  7311. +      
  7312. +      if (n->source != SELF) continue;
  7313. +      
  7314. +      if (name_type >= 0x1b && name_type <= 0x20 && 
  7315. +      ques_type >= 0x1b && ques_type <= 0x20)
  7316. +    {
  7317. +      if (!strequal(qname, n->name.name)) continue;
  7318. +    }
  7319. +      
  7320. +      count++;
  7321. +    }
  7322. +  
  7323. +  /* XXXX hack, we should calculate exactly how many will fit */
  7324. +  count = MIN(count,(sizeof(rdata) - 64) / 18);
  7325.    
  7326. -  buf = &nmb2->answers->rdata[0];
  7327. -  SCVAL(buf,0,count);
  7328. +  countptr = buf = rdata;
  7329.    buf += 1;
  7330. -
  7331. -  for (n = namelist ; n; n = n->next) 
  7332. +  
  7333. +  names_added = 0;
  7334. +  
  7335. +  for (n = namelist ; n && count >= 0; n = n->next) 
  7336.      {
  7337. +      int name_type = n->name.name_type;
  7338. +      
  7339.        if (n->source != SELF) continue;
  7340. -
  7341. +      
  7342. +      /* start with first bit of putting info in buffer: the name */
  7343. +      
  7344.        bzero(buf,18);
  7345. -      strcpy(buf,n->name.name);
  7346. +      StrnCpy(buf,n->name.name,15);
  7347.        strupper(buf);
  7348. -      buf[15] = n->name.name_type;
  7349. -      buf += 16;
  7350. -      buf[0] = 0x4; /* active */
  7351. -      if (!n->unique) buf[0] |= 0x80; /* group */
  7352. -      buf += 2;
  7353. +      
  7354. +      /* now check if we want to exclude other workgroup names
  7355. +     from the response. if we don't exclude them, windows clients
  7356. +     get confused and will respond with an error for NET VIEW */
  7357. +      
  7358. +      if (name_type >= 0x1b && name_type <= 0x20 && 
  7359. +      ques_type >= 0x1b && ques_type <= 0x20)
  7360. +    {
  7361. +      if (!strequal(qname, n->name.name)) continue;
  7362. +    }
  7363. +      
  7364. +      /* carry on putting name info in buffer */
  7365. +      
  7366. +      buf[15] = name_type;
  7367. +      buf[16]  = n->nb_flags;
  7368. +      
  7369. +      buf += 18;
  7370. +      
  7371.        count--;
  7372. +      names_added++;
  7373.      }
  7374. -
  7375. +  
  7376. +  if (count < 0)
  7377. +    {
  7378. +      DEBUG(3, (("too many names: missing a few!\n")));
  7379. +    }
  7380. +  
  7381. +  SCVAL(countptr,0,names_added);
  7382. +  
  7383.    /* XXXXXXX we should fill in more fields of the statistics structure */
  7384.    bzero(buf,64);
  7385.    {
  7386. @@ -1722,602 +612,456 @@
  7387.      SIVAL(buf,20,num_good_sends);
  7388.      SIVAL(buf,24,num_good_receives);
  7389.    }
  7390. +  
  7391.    SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
  7392. -
  7393. +  
  7394.    buf += 64;
  7395. -
  7396. -  nmb2->answers->rdlength = PTR_DIFF(buf,&nmb2->answers->rdata[0]);
  7397. -
  7398. -  send_packet(&p2);
  7399. +  
  7400. +  /* Send a POSITIVE NAME STATUS RESPONSE */
  7401. +  reply_netbios_packet(p,nmb->header.name_trn_id,0,0,
  7402. +               &nmb->question.question_name,
  7403. +               nmb->question.question_type,
  7404. +               nmb->question.question_class,
  7405. +               0,
  7406. +               rdata,PTR_DIFF(buf,rdata));
  7407.  }
  7408.  
  7409.  
  7410. -
  7411. -/****************************************************************************
  7412. -reply to a name query
  7413. -****************************************************************************/
  7414. -static void reply_name_query(struct packet_struct *p)
  7415. -{
  7416. -  struct nmb_packet *nmb = &p->packet.nmb;
  7417. -  char *qname = nmb->question.question_name.name;
  7418. -  BOOL wildcard = (qname[0] == '*'); 
  7419. -  BOOL bcast = nmb->header.nm_flags.bcast;
  7420. -  struct in_addr retip;
  7421. -  int name_type = nmb->question.question_name.name_type;
  7422. -  struct packet_struct p2;
  7423. -  struct nmb_packet *nmb2;
  7424. -  struct res_rec answer_rec;
  7425. -  int ttl=0;
  7426. -  int rcode=0;
  7427. -  BOOL unique = True;
  7428. -
  7429. -  DEBUG(3,("Name query for %s from %s (bcast=%s) - ",
  7430. -       namestr(&nmb->question.question_name),
  7431. -       inet_ntoa(p->ip),
  7432. -       BOOLSTR(bcast)));
  7433. -
  7434. -  if (wildcard)
  7435. -    retip = myip;
  7436. -
  7437. -  if (!wildcard) {
  7438. -    struct name_record *n = find_name(&nmb->question.question_name);
  7439. -
  7440. -    if (!n) {
  7441. -      struct in_addr ip;
  7442. +/***************************************************************************
  7443. +reply to a name query
  7444. +****************************************************************************/
  7445. +struct name_record *search_for_name(struct nmb_name *question,
  7446. +                    struct in_addr ip, int Time, int search)
  7447. +{
  7448. +  int name_type = question->name_type;
  7449. +  char *qname = question->name;
  7450. +  BOOL dns_type = name_type == 0x20 || name_type == 0;
  7451. +  
  7452. +  struct name_record *n;
  7453. +  
  7454. +  DEBUG(3,("Search for %s from %s - ", namestr(question), inet_ntoa(ip)));
  7455. +  
  7456. +  /* first look up name in cache */
  7457. +  n = find_name_search(question,search,ip);
  7458. +  
  7459. +  /* now try DNS lookup. */
  7460. +  if (!n)
  7461. +    {
  7462. +      struct in_addr dns_ip;
  7463.        unsigned long a;
  7464. -
  7465. +      
  7466.        /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
  7467. -      if (name_type != 0x20 && name_type != 0) {
  7468. -    DEBUG(3,("not found\n"));
  7469. -    return;
  7470. -      }
  7471. -
  7472. +      if (!dns_type)
  7473. +    {
  7474. +      DEBUG(3,("types 0x20 0x1b 0x0 only: name not found\n"));
  7475. +      return NULL;
  7476. +    }
  7477. +      
  7478.        /* look it up with DNS */      
  7479.        a = interpret_addr(qname);
  7480. -
  7481. -      putip((char *)&ip,(char *)&a);
  7482. -
  7483. -      if (!a) {
  7484. -    /* no luck with DNS. We could possibly recurse here XXXX */
  7485. -    /* if this isn't a bcast then we should send a negative reply XXXX */
  7486. -    DEBUG(3,("no recursion\n"));
  7487. -    add_host_entry(qname,name_type,True,60*60,DNSFAIL,ip);
  7488. -    return;
  7489. -      }
  7490. -
  7491. +      
  7492. +      putip((char *)&dns_ip,(char *)&a);
  7493. +      
  7494. +      if (!a)
  7495. +    {
  7496. +      /* no luck with DNS. We could possibly recurse here XXXX */
  7497. +      /* if this isn't a bcast then we should send a negative reply XXXX */
  7498. +      DEBUG(3,("no recursion\n"));
  7499. +      add_netbios_entry(qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip);
  7500. +      return NULL;
  7501. +    }
  7502. +      
  7503.        /* add it to our cache of names. give it 2 hours in the cache */
  7504. -      n = add_host_entry(qname,name_type,True,2*60*60,DNS,ip);
  7505. -
  7506. +      n = add_netbios_entry(qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip);
  7507. +      
  7508.        /* failed to add it? yikes! */
  7509. -      if (!n) return;
  7510. -    }
  7511. -
  7512. -    /* don't respond to bcast queries for group names unless we own them */
  7513. -    if (bcast && !n->unique && !n->source == SELF) {
  7514. -      DEBUG(3,("no bcast replies\n"));
  7515. -      return;
  7516. -    }
  7517. -
  7518. -    if (!lp_proxy_name_resolution() && n->source != SELF) {
  7519. -      DEBUG(3,("no proxy resolution\n"));
  7520. -      return;
  7521. -    }
  7522. -
  7523. -    /* don't respond to bcast queries for addresses on the same net as the 
  7524. -       machine doing the querying unless its our IP */
  7525. -    if (bcast && 
  7526. -    n->source != SELF && 
  7527. -    same_net(n->ip,p->ip)) {
  7528. -      DEBUG(3,("same net\n"));      
  7529. -      return;
  7530. +      if (!n) return NULL;
  7531.      }
  7532. -
  7533. -    /* is our entry already dead? */
  7534. -    if (n->death_time) {
  7535. -      if (n->death_time < p->timestamp) return;
  7536. -      ttl = n->death_time - p->timestamp;
  7537. +  
  7538. +  /* is our entry already dead? */
  7539. +  if (n->death_time)
  7540. +    {
  7541. +      if (n->death_time < Time) return False;
  7542.      }
  7543. -
  7544. -    retip = n->ip;
  7545. -    unique = n->unique;
  7546. -
  7547. -    /* it may have been an earlier failure */
  7548. -    if (n->source == DNSFAIL) {
  7549. +  
  7550. +  /* it may have been an earlier failure */
  7551. +  if (n->source == DNSFAIL)
  7552. +    {
  7553.        DEBUG(3,("DNSFAIL\n"));
  7554. -      return;
  7555. +      return NULL;
  7556.      }
  7557. -  }
  7558. -
  7559. -  /* if the IP is 0 then substitute my IP - we should see which one is on the 
  7560. -     right interface for the caller to do this right XXX */
  7561. -  if (zero_ip(retip)) retip = myip;
  7562.    
  7563. -  DEBUG(3,("OK %s rcode=%d\n",inet_ntoa(retip),rcode));      
  7564. -
  7565. -  /* a lot of fields get copied from the query. This gives us the IP
  7566. -     and port the reply will be sent to etc */
  7567. -  p2 = *p;
  7568. -  nmb2 = &p2.packet.nmb;
  7569. -
  7570. -  nmb2->header.response = True;
  7571. -  nmb2->header.nm_flags.bcast = False;
  7572. -  nmb2->header.nm_flags.recursion_available = CanRecurse;
  7573. -  nmb2->header.nm_flags.trunc = False;
  7574. -  nmb2->header.nm_flags.authoritative = True; /* WfWg ignores 
  7575. -                         non-authoritative answers */
  7576. -  nmb2->header.qdcount = 0;
  7577. -  nmb2->header.ancount = 1;
  7578. -  nmb2->header.nscount = 0;
  7579. -  nmb2->header.arcount = 0;
  7580. -  nmb2->header.rcode = rcode;
  7581. -
  7582. -  nmb2->answers = &answer_rec;
  7583. -  bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
  7584. -
  7585. -  nmb2->answers->rr_name = nmb->question.question_name;
  7586. -  nmb2->answers->rr_type = nmb->question.question_type;
  7587. -  nmb2->answers->rr_class = nmb->question.question_class;
  7588. -  nmb2->answers->ttl = ttl;
  7589. -  nmb2->answers->rdlength = 6;
  7590. -  nmb2->answers->rdata[0] = unique?0:0x80; 
  7591. -  nmb2->answers->rdata[1] = 0; 
  7592. -  putip(&nmb2->answers->rdata[2],(char *)&retip);
  7593. -
  7594. -  send_packet(&p2);
  7595. +  DEBUG(3,("OK %s\n",inet_ntoa(n->ip)));      
  7596. +  
  7597. +  return n;
  7598.  }
  7599.  
  7600. +/* XXXX i think we should only do this if we are a WINS proxy
  7601. +        if (!n && bcast)
  7602. +        {
  7603. +        // now try look up the name at the primary domain controller
  7604. +            if (*lp_domain_controller())
  7605. +            {
  7606. +                struct in_addr dom_ip;
  7607. +                dom_ip = *interpret_addr2(lp_domain_controller());
  7608. +
  7609. +                if (!zero_ip(dom_ip))
  7610. +                {
  7611. +                    struct in_addr found_ip;
  7612. +
  7613. +                    // initiate a netbios query to the PDC
  7614. +                    queue_netbios_packet(ClientNMB,NMB_QUERY,NAME_CONFIRM_QUERY,
  7615. +                                        question->name, question->name_type, 0,
  7616. +                                        False, True, dom_ip, id);
  7617. +                    return;
  7618. +                }
  7619. +            }
  7620. +        }
  7621. +*/
  7622.  
  7623. +/***************************************************************************
  7624. +reply to a name query.
  7625.  
  7626. -/* the global packet linked-list. incoming entries are added to the
  7627. -   end of this list.  it is supposed to remain fairly short so we
  7628. -   won't bother with an end pointer. */
  7629. -static struct packet_struct *packet_queue = NULL;
  7630. +with broadcast name queries:
  7631.  
  7632. +    - only reply if the query is for one of YOUR names. all other machines on
  7633. +      the network will be doing the same thing (that is, only replying to a
  7634. +      broadcast query if they own it)
  7635. +      NOTE: broadcast name queries should only be sent out by a machine
  7636. +      if they HAVEN'T been configured to use WINS. this is generally bad news
  7637. +      in a wide area tcp/ip network and should be rectified by the systems
  7638. +      administrator. USE WINS! :-)
  7639. +    - the exception to this is if the query is for a Primary Domain Controller
  7640. +      type name (0x1b), in which case, a reply is sent.
  7641.  
  7642. -/*******************************************************************
  7643. -  queue a packet into the packet queue
  7644. -  ******************************************************************/
  7645. -static void queue_packet(struct packet_struct *packet)
  7646. -{
  7647. -  struct packet_struct *p;
  7648. -  if (!packet_queue) {
  7649. -    packet->prev = NULL;
  7650. -    packet->next = NULL;
  7651. -    packet_queue = packet;
  7652. -    return;
  7653. -  }
  7654. -  
  7655. -  /* find the bottom */
  7656. -  for (p=packet_queue;p->next;p=p->next) ;
  7657. +    - NEVER send a negative response to a broadcast query. no-one else will!
  7658.  
  7659. -  p->next = packet;
  7660. -  packet->next = NULL;
  7661. -  packet->prev = p;
  7662. -}
  7663. +with directed name queries:
  7664.  
  7665. -/****************************************************************************
  7666. -  process a nmb packet
  7667. -  ****************************************************************************/
  7668. -static void process_nmb(struct packet_struct *p)
  7669. +    - if you are the WINS server, you are expected to 
  7670. +****************************************************************************/
  7671. +extern void reply_name_query(struct packet_struct *p)
  7672.  {
  7673.    struct nmb_packet *nmb = &p->packet.nmb;
  7674. -
  7675. -  /* if this is a response then ignore it */
  7676. -  if (nmb->header.response) return;
  7677. -
  7678. -  switch (nmb->header.opcode) 
  7679. +  struct nmb_name *question = &nmb->question.question_name;
  7680. +  int name_type = question->name_type;
  7681. +  BOOL dns_type = name_type == 0x20 || name_type == 0;
  7682. +  BOOL bcast = nmb->header.nm_flags.bcast;
  7683. +  int ttl=0;
  7684. +  int rcode = 0;
  7685. +  int nb_flags = 0;
  7686. +  struct in_addr retip;
  7687. +  char rdata[6];
  7688. +  
  7689. +  struct in_addr gp_ip = *interpret_addr2("255.255.255.255");
  7690. +  BOOL success = True;
  7691. +  
  7692. +  struct name_record *n;
  7693. +  enum name_search search = dns_type || name_type == 0x1b ?
  7694. +    FIND_GLOBAL : FIND_SELF;
  7695. +  
  7696. +  DEBUG(3,("Name query "));
  7697. +  
  7698. +  if ((n = search_for_name(question,p->ip,p->timestamp, search)))
  7699.      {
  7700. -    case 5:
  7701. -    case 8:
  7702. -    case 9:
  7703. -      if (nmb->header.qdcount>0 && 
  7704. -      nmb->header.arcount>0) {
  7705. -    reply_name_reg(p);
  7706. -    return;
  7707. -      }
  7708. -      break;
  7709. -
  7710. -    case 0:
  7711. -      if (nmb->header.qdcount>0) 
  7712. +      /* don't respond to broadcast queries unless the query is for
  7713. +     a name we own or it is for a Primary Domain Controller name */
  7714. +      if (bcast && n->source != SELF && name_type != 0x1b)
  7715.      {
  7716. -      switch (nmb->question.question_type)
  7717. -        {
  7718. -        case 0x20:
  7719. -          reply_name_query(p);
  7720. -          break;
  7721. -
  7722. -        case 0x21:
  7723. -          reply_name_status(p);
  7724. -          break;
  7725. -        }
  7726. -      return;
  7727. +      if (!lp_wins_proxy() || same_net(p->ip,n->ip,Netmask)) {
  7728. +        /* never reply with a negative response to broadcast queries */
  7729. +        return;
  7730. +      }
  7731.      }
  7732. -      break;
  7733. -
  7734. -    case 6:
  7735. -      if (nmb->header.qdcount>0 && 
  7736. -      nmb->header.arcount>0) {
  7737. -    reply_name_release(p);
  7738. -    return;
  7739. -      }
  7740. -      break;
  7741. +      
  7742. +      /* we will reply */
  7743. +      ttl = n->death_time - p->timestamp;
  7744. +      retip = n->ip;
  7745. +      nb_flags = n->nb_flags;
  7746.      }
  7747. -
  7748. -}
  7749. -
  7750. -
  7751. -
  7752. -/*******************************************************************
  7753. -  run elements off the packet queue till its empty
  7754. -  ******************************************************************/
  7755. -static void run_packet_queue(void)
  7756. -{
  7757. -  struct packet_struct *p;
  7758. -
  7759. -  while ((p=packet_queue)) {
  7760. -    switch (p->packet_type)
  7761. -      {
  7762. -      case NMB_PACKET:
  7763. -    process_nmb(p);
  7764. -    break;
  7765. -
  7766. -      case DGRAM_PACKET:
  7767. -    process_dgram(p);
  7768. -    break;
  7769. -      }
  7770. -
  7771. -    packet_queue = packet_queue->next;
  7772. -    if (packet_queue) packet_queue->prev = NULL;
  7773. -    free_packet(p);
  7774. -  }
  7775. -}
  7776. -
  7777. -
  7778. -/****************************************************************************
  7779. -  The main select loop, listen for packets and respond
  7780. -  ***************************************************************************/
  7781. -void process(void)
  7782. -{
  7783. -
  7784. -  while (True)
  7785. -    {
  7786. -      fd_set fds;
  7787. -      int selrtn;
  7788. -      struct timeval timeout;
  7789. -
  7790. -      if (needelection && PrimaryGroup[0] && !RunningElection) {
  7791. -    DEBUG(3,(">>> Starting election on %s <<<\n",PrimaryGroup));
  7792. -    ElectionCount = 0;
  7793. -    RunningElection = True;
  7794. -    needelection = False;
  7795. -      }
  7796. -
  7797. -      FD_ZERO(&fds);
  7798. -      FD_SET(ClientNMB,&fds);
  7799. -      FD_SET(ClientDGRAM,&fds);
  7800. -      /* during elections we need to send election packets at one
  7801. -         second intervals */
  7802. -      timeout.tv_sec = RunningElection?1:NMBD_SELECT_LOOP;
  7803. -      timeout.tv_usec = 0;
  7804. -
  7805. -      selrtn = sys_select(&fds,&timeout);
  7806. -
  7807. -      if (FD_ISSET(ClientNMB,&fds)) {
  7808. -    struct packet_struct *packet = read_packet(ClientNMB,NMB_PACKET);
  7809. -    if (packet) queue_packet(packet);
  7810. -      }
  7811. -
  7812. -      if (FD_ISSET(ClientDGRAM,&fds)) {
  7813. -    struct packet_struct *packet = read_packet(ClientDGRAM,DGRAM_PACKET);
  7814. -    if (packet) queue_packet(packet);
  7815. -      }
  7816. -
  7817. -      if (RunningElection) 
  7818. -    run_election();
  7819. -
  7820. -      run_packet_queue();
  7821. -
  7822. -      do_announcements();
  7823. -
  7824. -      housekeeping();
  7825. +  else
  7826. +    {
  7827. +      if (bcast) return; /* never reply negative response to bcasts */
  7828. +      success = False;
  7829.      }
  7830. -}
  7831. -
  7832. +  
  7833. +  /* if asking for a group name (type 0x1e) return 255.255.255.255 */
  7834. +  if (ip_equal(retip, gp_ip) && name_type == 0x1e) retip = gp_ip;
  7835.  
  7836. -/****************************************************************************
  7837. -  open the socket communication
  7838. -****************************************************************************/
  7839. -static BOOL open_sockets(BOOL isdaemon,int port)
  7840. -{
  7841. -  struct hostent *hp;
  7842. -  /* get host info */
  7843. -  if ((hp = Get_Hostbyname(myhostname)) == 0) 
  7844. -    {
  7845. -      DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
  7846. -      return False;
  7847. -    }   
  7848. +  /* if the IP is 0 then substitute my IP - we should see which one is on the 
  7849. +     right interface for the caller to do this right XXX */
  7850. +  if (zero_ip(retip)) retip = myip;
  7851.  
  7852. -  if (isdaemon)
  7853. -    ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
  7854. +  if (success)
  7855. +    {
  7856. +      rcode = 0;
  7857. +      DEBUG(3,("OK %s\n",inet_ntoa(retip)));      
  7858. +    }
  7859.    else
  7860. -    ClientNMB = 0;
  7861. -
  7862. -  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
  7863. -
  7864. -  if (ClientNMB == -1)
  7865. -    return(False);
  7866. -
  7867. -  signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  7868. -
  7869. -  set_socket_options(ClientNMB,"SO_BROADCAST");
  7870. -  set_socket_options(ClientDGRAM,"SO_BROADCAST");
  7871. -
  7872. -  DEBUG(3, ("Socket opened.\n"));
  7873. -  return True;
  7874. +    {
  7875. +      rcode = 3;
  7876. +      DEBUG(3,("UNKNOWN\n"));      
  7877. +    }
  7878. +  
  7879. +  if (success)
  7880. +    {
  7881. +      rdata[0] = nb_flags;
  7882. +      rdata[1] = 0;
  7883. +      putip(&rdata[2],(char *)&retip);
  7884. +    }
  7885. +  
  7886. +  reply_netbios_packet(p,nmb->header.name_trn_id,rcode,0,
  7887. +               &nmb->question.question_name,
  7888. +               nmb->question.question_type,
  7889. +               nmb->question.question_class,
  7890. +               ttl,
  7891. +               rdata, success ? 6 : 0);
  7892.  }
  7893.  
  7894.  
  7895. -/*******************************************************************
  7896. -  check that a IP, bcast and netmask and consistent. Must be a 1s
  7897. -  broadcast
  7898. -  ******************************************************************/
  7899. -static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast,
  7900. -              struct in_addr nmask)
  7901. -{
  7902. -  unsigned long a_ip,a_bcast,a_nmask;
  7903. -
  7904. -  a_ip = ntohl(ip.s_addr);
  7905. -  a_bcast = ntohl(bcast.s_addr);
  7906. -  a_nmask = ntohl(nmask.s_addr);
  7907. -
  7908. -  /* check the netmask is sane */
  7909. -  if (((a_nmask>>24)&0xFF) != 0xFF) {
  7910. -    DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask)));
  7911. -    return(False);
  7912. -  }
  7913. -
  7914. -  /* check the IP and bcast are on the same net */
  7915. -  if ((a_ip&a_nmask) != (a_bcast&a_nmask)) {
  7916. -    DEBUG(0,("IP and broadcast are on different nets!\n"));
  7917. -    return(False);
  7918. -  }
  7919. -
  7920. -  /* check the IP and bcast are on the same net */
  7921. -  if ((a_bcast|a_nmask) != 0xFFFFFFFF) {
  7922. -    DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast)));
  7923. -    return(False);
  7924. -  }
  7925. -
  7926. -  return(True);
  7927. -}
  7928. -
  7929.  /****************************************************************************
  7930. -  initialise connect, service and file structs
  7931. +response from a name query
  7932.  ****************************************************************************/
  7933. -static BOOL init_structs(void )
  7934. +static void response_netbios_packet(struct packet_struct *p)
  7935.  {
  7936. -  if (!get_myname(myhostname,got_myip?NULL:&myip))
  7937. -    return(False);
  7938. -
  7939. -  /* Read the broadcast address from the interface */
  7940. -  {
  7941. -    struct in_addr ip0,ip1,ip2;
  7942. -
  7943. -    ip0 = myip;
  7944. -
  7945. -    if (!(got_bcast && got_nmask))
  7946. -      {
  7947. -    get_broadcast(&ip0,&ip1,&ip2);
  7948. +  struct nmb_packet *nmb = &p->packet.nmb;
  7949. +  struct nmb_name *question = &nmb->question.question_name;
  7950. +  char *qname = question->name;
  7951. +  BOOL bcast = nmb->header.nm_flags.bcast;
  7952. +  struct name_response_record *n;
  7953.  
  7954. -    if (!got_myip)
  7955. -      myip = ip0;
  7956. -    
  7957. -    if (!got_bcast)
  7958. -      bcast_ip = ip1;
  7959. -    
  7960. -    if (!got_nmask)
  7961. -      Netmask = ip2;   
  7962. -      } 
  7963. -
  7964. -    DEBUG(1,("Using IP %s  ",inet_ntoa(myip))); 
  7965. -    DEBUG(1,("broadcast %s  ",inet_ntoa(bcast_ip)));
  7966. -    DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));    
  7967. -
  7968. -    if (!ip_consistent(myip,bcast_ip,Netmask)) {
  7969. -      DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n"));
  7970. -      DEBUG(0,("You are likely to experience problems with this setup!\n"));
  7971. +  if (nmb->answers == NULL)
  7972. +    {
  7973. +      DEBUG(3,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
  7974. +           inet_ntoa(p->ip),
  7975. +           BOOLSTR(bcast)));
  7976. +      return;
  7977.      }
  7978. +  
  7979. +  if (nmb->answers->rr_type == NMB_STATUS) {
  7980. +    DEBUG(3,("Name status "));
  7981.    }
  7982.  
  7983. -  if (! *myname) {
  7984. -    char *p;
  7985. -    strcpy(myname,myhostname);
  7986. -    p = strchr(myname,'.');
  7987. -    if (p) *p = 0;
  7988. +  if (nmb->answers->rr_type == NMB_QUERY)    {
  7989. +    DEBUG(3,("Name query "));
  7990.    }
  7991.  
  7992. -  {
  7993. -    extern fstring local_machine;
  7994. -    strcpy(local_machine,myname);
  7995. -    strupper(local_machine);
  7996. +  if (nmb->answers->rr_type == NMB_REG) {
  7997. +    DEBUG(3,("Name registration "));
  7998.    }
  7999.  
  8000. -  return True;
  8001. -}
  8002. -
  8003. -/****************************************************************************
  8004. -usage on the program
  8005. -****************************************************************************/
  8006. -static void usage(char *pname)
  8007. -{
  8008. -  DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
  8009. -
  8010. -  printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
  8011. -  printf("Version %s\n",VERSION);
  8012. -  printf("\t-D                    become a daemon\n");
  8013. -  printf("\t-p port               listen on the specified port\n");
  8014. -  printf("\t-d debuglevel         set the debuglevel\n");
  8015. -  printf("\t-l log basename.      Basename for log/debug files\n");
  8016. -  printf("\t-n netbiosname.       the netbios name to advertise for this host\n");
  8017. -  printf("\t-B broadcast address  the address to use for broadcasts\n");
  8018. -  printf("\t-N netmask           the netmask to use for subnet determination\n");
  8019. -  printf("\t-H hosts file        load a netbios hosts file\n");
  8020. -  printf("\t-I ip-address        override the IP address\n");
  8021. -  printf("\t-G group name        add a group name to be part of\n");
  8022. -  printf("\t-C comment           sets the machine comment that appears in browse lists\n");
  8023. -  printf("\n");
  8024. -}
  8025. -
  8026. -
  8027. -/****************************************************************************
  8028. -  main program
  8029. -  **************************************************************************/
  8030. -int main(int argc,char *argv[])
  8031. -{
  8032. -  int port = NMB_PORT;
  8033. -  int opt;
  8034. -  extern FILE *dbf;
  8035. -  extern char *optarg;
  8036. -
  8037. -  *host_file = 0;
  8038. -
  8039. -#if 0
  8040. -  sleep(10);
  8041. -#endif
  8042. -
  8043. -  StartupTime = time(NULL);
  8044. -
  8045. -  TimeInit();
  8046. -
  8047. -  strcpy(debugf,NMBLOGFILE);
  8048. -
  8049. -  setup_logging(argv[0],False);
  8050. +  if (nmb->answers->rr_type == NMB_REL) {
  8051. +    DEBUG(3,("Name release "));
  8052. +  }
  8053.  
  8054. -  charset_initialise();
  8055. +  DEBUG(3,("response for %s from %s (bcast=%s)\n",
  8056. +       namestr(&nmb->answers->rr_name),
  8057. +       inet_ntoa(p->ip),
  8058. +       BOOLSTR(bcast)));
  8059. +  
  8060. +  if (!(n = find_name_query(nmb->header.name_trn_id))) {
  8061. +    DEBUG(3,("unknown response (received too late or from nmblookup?)\n"));
  8062. +    return;
  8063. +  }
  8064.  
  8065. -#ifdef LMHOSTSFILE
  8066. -  strcpy(host_file,LMHOSTSFILE);
  8067. -#endif
  8068. +  n->num_msgs++; /* count number of responses received */
  8069.  
  8070. -  /* this is for people who can't start the program correctly */
  8071. -  while (argc > 1 && (*argv[1] != '-'))
  8072. +  switch (n->cmd_type)
  8073.      {
  8074. -      argv++;
  8075. -      argc--;
  8076. +    case MASTER_SERVER_CHECK     : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
  8077. +    case SERVER_CHECK            : DEBUG(4,("SERVER_CHECK\n")); break;
  8078. +    case FIND_MASTER             : DEBUG(4,("FIND_MASTER\n")); break;
  8079. +    case NAME_STATUS_MASTER_CHECK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
  8080. +    case NAME_STATUS_CHECK       : DEBUG(4,("NAME_STATUS_CHECK\n")); break;
  8081. +    case CHECK_MASTER            : DEBUG(4,("CHECK_MASTER\n")); break;
  8082. +    case NAME_CONFIRM_QUERY      : DEBUG(4,("NAME_CONFIRM_QUERY\n")); break;
  8083. +    default: break;
  8084.      }
  8085. -
  8086. -  fault_setup(fault_continue);
  8087. -
  8088. -  signal(SIGHUP,SIGNAL_CAST sig_hup);
  8089. -
  8090. -  bcast_ip = *interpret_addr2("0.0.0.0");
  8091. -  myip = *interpret_addr2("0.0.0.0");
  8092. -
  8093. -  while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
  8094. -    switch (opt)
  8095. +  switch (n->cmd_type)
  8096. +    {
  8097. +    case MASTER_SERVER_CHECK:
  8098. +    case SERVER_CHECK:
  8099. +    case FIND_MASTER:
  8100.        {
  8101. -      case 's':
  8102. -    strcpy(servicesf,optarg);
  8103. -    break;
  8104. -      case 'C':
  8105. -    strcpy(ServerComment,optarg);
  8106. -    break;
  8107. -      case 'G':
  8108. -    add_domain_entry(optarg,bcast_ip);
  8109. -    break;
  8110. -      case 'H':
  8111. -    strcpy(host_file,optarg);
  8112. -    break;
  8113. -      case 'I':
  8114. -    myip = *interpret_addr2(optarg);
  8115. -    got_myip = True;
  8116. -    break;
  8117. -      case 'B':
  8118. -    bcast_ip = *interpret_addr2(optarg);
  8119. -    got_bcast = True;
  8120. -    break;
  8121. -      case 'N':
  8122. -    Netmask = *interpret_addr2(optarg);
  8123. -    got_nmask = True;
  8124. -    break;
  8125. -      case 'n':
  8126. -    strcpy(myname,optarg);
  8127. -    break;
  8128. -      case 'l':
  8129. -    sprintf(debugf,"%s.nmb",optarg);
  8130. -    break;
  8131. -      case 'i':
  8132. -    strcpy(scope,optarg);
  8133. -    strupper(scope);
  8134. -    break;
  8135. -      case 'D':
  8136. -    is_daemon = True;
  8137. +    if (nmb->answers->rr_type == NMB_QUERY)
  8138. +      {
  8139. +        enum cmd_type cmd = (n->cmd_type == MASTER_SERVER_CHECK) ?
  8140. +          NAME_STATUS_MASTER_CHECK :
  8141. +          NAME_STATUS_CHECK;
  8142. +        if (n->num_msgs > 1 && !strequal(qname,n->name.name))
  8143. +          {
  8144. +        /* one subnet, one master browser per workgroup */
  8145. +        /* XXXX force an election? */
  8146. +        DEBUG(1,("more than one master browser replied!\n"));
  8147. +          }
  8148. +        
  8149. +        /* initiate a name status check on the server that replied */
  8150. +        queue_netbios_packet(ClientNMB,NMB_STATUS, cmd,
  8151. +                 nmb->answers->rr_name.name,
  8152. +                 nmb->answers->rr_name.name_type,0,
  8153. +                 False,False,n->to_ip);
  8154. +      }
  8155. +    else
  8156. +      {
  8157. +        DEBUG(1,("Name query reply has wrong answer rr_type\n"));
  8158. +      }
  8159.      break;
  8160. -      case 'd':
  8161. -    DEBUGLEVEL = atoi(optarg);
  8162. +      }
  8163. +      
  8164. +    case NAME_STATUS_MASTER_CHECK:
  8165. +    case NAME_STATUS_CHECK:
  8166. +      {
  8167. +    if (nmb->answers->rr_type == NMB_STATUS)
  8168. +      {
  8169. +        /* NMB_STATUS arrives: contains the workgroup name 
  8170. +           and server name we require */
  8171. +        struct nmb_name name;
  8172. +        fstring serv_name;
  8173. +        
  8174. +        if (interpret_node_status(nmb->answers->rdata,
  8175. +                      &name,0x1d,serv_name,n->to_ip))
  8176. +          {
  8177. +        if (*serv_name)
  8178. +          {
  8179. +            sync_server(n->cmd_type,serv_name,
  8180. +                name.name,name.name_type,
  8181. +                n->to_ip);
  8182. +          }
  8183. +          }
  8184. +        else
  8185. +          {
  8186. +        DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
  8187. +          }
  8188. +      }
  8189. +    else
  8190. +      {
  8191. +        DEBUG(1,("Name status reply has wrong answer rr_type\n"));
  8192. +      }
  8193.      break;
  8194. -      case 'p':
  8195. -    port = atoi(optarg);
  8196. +      }
  8197. +      
  8198. +    case CHECK_MASTER:
  8199. +      {
  8200. +    /* no action required here. it's when NO responses are received
  8201. +       that we need to do something (see expire_name_query_entries) */
  8202. +    
  8203. +    DEBUG(4, ("Master browser exists for %s at %s\n",
  8204. +          namestr(&n->name),
  8205. +          inet_ntoa(n->to_ip)));
  8206. +    if (n->num_msgs > 1)
  8207. +      {
  8208. +        DEBUG(1,("more than one master browser!\n"));
  8209. +      }
  8210. +    if (nmb->answers->rr_type != NMB_QUERY)
  8211. +      {
  8212. +        DEBUG(1,("Name query reply has wrong answer rr_type\n"));
  8213. +      }
  8214.      break;
  8215. -      case 'h':
  8216. -    usage(argv[0]);
  8217. -    exit(0);
  8218. +      }
  8219. +    case NAME_CONFIRM_QUERY:
  8220. +      {
  8221. +    DEBUG(4, ("Name query at WINS server: %s at %s - ",
  8222. +          namestr(&n->name),
  8223. +          inet_ntoa(n->to_ip)));
  8224. +    if (nmb->header.rcode == 0 && nmb->answers->rdata)
  8225. +      {
  8226. +        int nb_flags = nmb->answers->rdata[0];
  8227. +        struct in_addr found_ip;
  8228. +        putip((char*)&found_ip,&nmb->answers->rdata[2]);
  8229. +        
  8230. +        DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
  8231. +        add_netbios_entry(nmb->answers->rr_name.name,
  8232. +                  nmb->answers->rr_name.name_type,
  8233. +                  nb_flags,GET_TTL(0),STATUS_QUERY,found_ip);
  8234. +      }
  8235. +    else
  8236. +      {
  8237. +        DEBUG(4, (" NEGATIVE RESPONSE\n"));
  8238. +      }
  8239. +    
  8240.      break;
  8241. -      default:
  8242. -    if (!is_a_socket(0))
  8243. -      usage(argv[0]);
  8244. +      }
  8245. +    default:
  8246. +      {
  8247. +    DEBUG(0,("unknown command received in response_netbios_packet\n"));
  8248.      break;
  8249.        }
  8250. -  
  8251. -  DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
  8252. -  DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
  8253. -
  8254. -  init_structs();
  8255. -
  8256. -  if (!reload_services(False))
  8257. -    return(-1);    
  8258. -
  8259. -  if (*host_file)
  8260. -    {
  8261. -      load_hosts_file(host_file);
  8262. -      DEBUG(3,("Loaded hosts file\n"));
  8263.      }
  8264. +}
  8265.  
  8266. -  if (!*ServerComment)
  8267. -    strcpy(ServerComment,"Samba %v");
  8268. -  string_sub(ServerComment,"%v",VERSION);
  8269. -  string_sub(ServerComment,"%h",myhostname);
  8270. -
  8271. -  add_my_names();
  8272. -
  8273. -  DEBUG(3,("Checked names\n"));
  8274. -  
  8275. -  dump_names();
  8276. -
  8277. -  DEBUG(3,("Dumped names\n"));
  8278. -
  8279. -  if (!is_daemon && !is_a_socket(0)) {
  8280. -    DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  8281. -    is_daemon = True;
  8282. -  }
  8283. -  
  8284. -
  8285. -  if (is_daemon) {
  8286. -    DEBUG(2,("%s becoming a daemon\n",timestring()));
  8287. -    become_daemon();
  8288. -  }
  8289.  
  8290. +/****************************************************************************
  8291. +  process a nmb packet
  8292. +  ****************************************************************************/
  8293. +void process_nmb(struct packet_struct *p)
  8294. +{
  8295. +    struct nmb_packet *nmb = &p->packet.nmb;
  8296.  
  8297. -  DEBUG(3,("Opening sockets\n"));
  8298. +    debug_nmb_packet(p);
  8299.  
  8300. -  if (open_sockets(is_daemon,port))
  8301. -    {
  8302. -      process();
  8303. -      close_sockets();
  8304. -    }
  8305. +    switch (nmb->header.opcode) 
  8306. +    {
  8307. +        case 5:
  8308. +        case 8:
  8309. +        case 9:
  8310. +        {
  8311. +            if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
  8312. +            if (nmb->header.response)
  8313. +                response_name_reg(p);
  8314. +            else
  8315. +                reply_name_reg(p);
  8316. +            break;
  8317. +        }
  8318. +
  8319. +        case 0:
  8320. +        {
  8321. +            if (nmb->header.response)
  8322. +            {
  8323. +                switch (nmb->question.question_type)
  8324. +                {
  8325. +                    case 0x0:
  8326. +                    {
  8327. +                        response_netbios_packet(p);
  8328. +                        break;
  8329. +                    }
  8330. +                }
  8331. +                return;
  8332. +            }
  8333. +            else if (nmb->header.qdcount>0) 
  8334. +            {
  8335. +                switch (nmb->question.question_type)
  8336. +                {
  8337. +                    case NMB_QUERY:
  8338. +                    {
  8339. +                        reply_name_query(p);
  8340. +                        break;
  8341. +                    }
  8342. +                    case NMB_STATUS:
  8343. +                    {
  8344. +                        reply_name_status(p);
  8345. +                        break;
  8346. +                    }
  8347. +                }
  8348. +                return;
  8349. +            }
  8350. +            break;
  8351. +        }
  8352. +
  8353. +        case 6:
  8354. +        {
  8355. +            if (nmb->header.qdcount==0 || nmb->header.arcount==0)
  8356. +            {
  8357. +                DEBUG(2,("netbios release packet rejected\n"));
  8358. +                break;
  8359. +            }
  8360. +
  8361. +            if (nmb->header.response)
  8362. +                response_name_release(p);
  8363. +            else
  8364. +                reply_name_release(p);
  8365. +            break;
  8366. +        }
  8367. +    }
  8368.  
  8369. -  if (dbf)
  8370. -    fclose(dbf);
  8371. -  return(0);
  8372.  }
  8373. +
  8374. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nameserv.h samba-1.9.16alpha5/source/nameserv.h
  8375. --- samba-1.9.16alpha4/source/nameserv.h    Sat May  4 17:50:24 1996
  8376. +++ samba-1.9.16alpha5/source/nameserv.h    Wed Jun  5 01:16:27 1996
  8377. @@ -20,16 +20,57 @@
  8378.     
  8379.  */
  8380.  
  8381. -#define MAX_DGRAM_SIZE 576
  8382. +/* NTAS uses 2, NT uses 1, WfWg uses 0 */
  8383. +#define MAINTAIN_LIST    2
  8384. +#define ELECTION_VERSION 2
  8385. +
  8386. +#define MAX_DGRAM_SIZE (80*18+64)
  8387.  #define MIN_DGRAM_SIZE 12
  8388.  
  8389. -#define NMB_PORT 137
  8390. -#define DGRAM_PORT 138
  8391. -#define SMB_PORT 139
  8392. +#define NMB_QUERY  0x20
  8393. +#define NMB_STATUS 0x21
  8394. +#define NMB_REG    0x05
  8395. +#define NMB_REL    0x06
  8396. +
  8397. +#define NB_GROUP  0x80
  8398. +#define NB_PERM   0x02
  8399. +#define NB_ACTIVE 0x04
  8400. +#define NB_CONFL  0x08
  8401. +#define NB_DEREG  0x10
  8402. +#define NB_BFLAG  0x00
  8403. +#define NB_PFLAG  0x20
  8404. +#define NB_MFLAG  0x40
  8405. +#define NB__FLAG  0x60
  8406. +#define NB_FLGMSK 0x60
  8407. +
  8408. +#define REFRESH_TIME (15*60)
  8409. +
  8410. +#define NAME_PERMANENT(p) ((p) & NB_PERM)
  8411. +#define NAME_ACTIVE(p)    ((p) & NB_ACTIVE)
  8412. +#define NAME_CONFLICT(p)  ((p) & NB_CONFL)
  8413. +#define NAME_DEREG(p)     ((p) & NB_DEREG)
  8414. +#define NAME_GROUP(p)     ((p) & NB_GROUP)
  8415. +
  8416. +#define NAME_BFLAG(p)     (((p) & NB_FLGMSK) == NB_BFLAG)
  8417. +#define NAME_PFLAG(p)     (((p) & NB_FLGMSK) == NB_PFLAG)
  8418. +#define NAME_MFLAG(p)     (((p) & NB_FLGMSK) == NB_MFLAG)
  8419. +#define NAME__FLAG(p)     (((p) & NB_FLGMSK) == NB__FLAG)
  8420.  
  8421. -enum name_source {LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
  8422. +enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
  8423.  enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
  8424.  enum packet_type {NMB_PACKET, DGRAM_PACKET};
  8425. +enum cmd_type
  8426. +{
  8427. +    NAME_STATUS_MASTER_CHECK,
  8428. +    NAME_STATUS_CHECK,
  8429. +    MASTER_SERVER_CHECK,
  8430. +    SERVER_CHECK,
  8431. +    FIND_MASTER,
  8432. +    CHECK_MASTER,
  8433. +    NAME_REGISTER,
  8434. +    NAME_RELEASE,
  8435. +    NAME_CONFIRM_QUERY
  8436. +};
  8437.  
  8438.  /* a netbios name structure */
  8439.  struct nmb_name {
  8440. @@ -46,32 +87,73 @@
  8441.    struct nmb_name name;
  8442.    time_t death_time;
  8443.    struct in_addr ip;
  8444. -  BOOL unique;
  8445. +  int nb_flags;
  8446.    enum name_source source;
  8447.  };
  8448.  
  8449. -/* this is used by the list of domains */
  8450. -struct domain_record
  8451. +/* browse and backup server cache for synchronising browse list */
  8452. +struct browse_cache_record
  8453.  {
  8454. -  struct domain_record *next;
  8455. -  struct domain_record *prev;
  8456. -  fstring name;
  8457. -  time_t lastannounce_time;
  8458. -  int announce_interval;
  8459. -  struct in_addr bcast_ip;
  8460. +    struct browse_cache_record *next;
  8461. +    struct browse_cache_record *prev;
  8462. +
  8463. +    pstring name;
  8464. +    int type;
  8465. +    pstring group;
  8466. +    struct in_addr ip;
  8467. +    time_t sync_time;
  8468. +    BOOL synced;
  8469.  };
  8470.  
  8471. -/* this is used to hold the list of servers in my domain */
  8472. +/* this is used to hold the list of servers in my domain, and is */
  8473. +/* contained within lists of domains */
  8474.  struct server_record
  8475.  {
  8476.    struct server_record *next;
  8477.    struct server_record *prev;
  8478. -  fstring name;
  8479. -  fstring comment;
  8480. -  uint32 servertype;
  8481. +
  8482. +  struct server_info_struct serv;
  8483.    time_t death_time;  
  8484.  };
  8485.  
  8486. +/* a workgroup structure. it contains a list of servers */
  8487. +struct work_record
  8488. +{
  8489. +  struct work_record *next;
  8490. +  struct work_record *prev;
  8491. +
  8492. +  struct server_record *serverlist;
  8493. +
  8494. +  /* work group info */
  8495. +  fstring work_group;
  8496. +  int     token;        /* used when communicating with backup browsers */
  8497. +  int     ServerType;
  8498. +
  8499. +  /* announce info */
  8500. +  time_t lastannounce_time;
  8501. +  int announce_interval;
  8502. +  BOOL    needannounce;
  8503. +
  8504. +  /* election info */
  8505. +  BOOL    RunningElection;
  8506. +  BOOL    needelection;
  8507. +  int     ElectionCount;
  8508. +  uint32  ElectionCriterion;
  8509. +};
  8510. +
  8511. +/* a domain structure. it contains a list of workgroups */
  8512. +struct domain_record
  8513. +{
  8514. +  struct domain_record *next;
  8515. +  struct domain_record *prev;
  8516. +
  8517. +  struct work_record *workgrouplist;
  8518. +
  8519. +  struct in_addr bcast_ip;
  8520. +  struct in_addr mask_ip;
  8521. +  struct in_addr myip;
  8522. +};
  8523. +
  8524.  /* a resource record */
  8525.  struct res_rec {
  8526.    struct nmb_name rr_name;
  8527. @@ -115,6 +197,25 @@
  8528.  };
  8529.  
  8530.  
  8531. +/* initiated name queries recorded in this list to track any responses... */
  8532. +struct name_response_record
  8533. +{
  8534. +  struct name_response_record *next;
  8535. +  struct name_response_record *prev;
  8536. +
  8537. +  uint16 response_id;
  8538. +  enum cmd_type cmd_type;
  8539. +
  8540. +  int fd;
  8541. +  struct nmb_name name;
  8542. +  BOOL bcast;
  8543. +  BOOL recurse;
  8544. +  struct in_addr to_ip;
  8545. +
  8546. +  time_t start_time;
  8547. +  int num_msgs;
  8548. +};
  8549. +
  8550.  /* a datagram - this normally contains SMB data in the data[] array */
  8551.  struct dgram_packet {
  8552.    struct {
  8553. @@ -154,31 +255,3 @@
  8554.  };
  8555.  
  8556.  
  8557. -/* this defines a list of network interfaces */
  8558. -struct net_interface {
  8559. -  struct net_interface *next;
  8560. -  struct in_addr ip;
  8561. -  struct in_addr bcast;
  8562. -  struct in_addr netmask;
  8563. -};
  8564. -
  8565. -
  8566. -/* prototypes */
  8567. -void free_nmb_packet(struct nmb_packet *nmb);
  8568. -void free_packet(struct packet_struct *packet);
  8569. -struct packet_struct *read_packet(int fd,enum packet_type packet_type);
  8570. -BOOL send_packet(struct packet_struct *p);
  8571. -struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
  8572. -void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
  8573. -BOOL name_query(int fd,char *name,int name_type,
  8574. -               BOOL bcast,BOOL recurse,
  8575. -               struct in_addr to_ip, struct in_addr *ip,void (*fn)());
  8576. -BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  8577. -         struct in_addr to_ip,char *master,char *rname,
  8578. -         void (*fn)());
  8579. -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
  8580. -             char *srcname,char *dstname,
  8581. -             int src_type,int dest_type,
  8582. -             struct in_addr dest_ip,
  8583. -             struct in_addr src_ip);
  8584. -char *namestr(struct nmb_name *n);
  8585. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/namework.c samba-1.9.16alpha5/source/namework.c
  8586. --- samba-1.9.16alpha4/source/namework.c    Thu Jan  1 10:00:00 1970
  8587. +++ samba-1.9.16alpha5/source/namework.c    Wed Jun  5 01:14:26 1996
  8588. @@ -0,0 +1,1070 @@
  8589. +/* 
  8590. +   Unix SMB/Netbios implementation.
  8591. +   Version 1.9.
  8592. +   NBT netbios routines and daemon - version 2
  8593. +   Copyright (C) Andrew Tridgell 1994-1995
  8594. +   
  8595. +   This program is free software; you can redistribute it and/or modify
  8596. +   it under the terms of the GNU General Public License as published by
  8597. +   the Free Software Foundation; either version 2 of the License, or
  8598. +   (at your option) any later version.
  8599. +   
  8600. +   This program is distributed in the hope that it will be useful,
  8601. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  8602. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  8603. +   GNU General Public License for more details.
  8604. +   
  8605. +   You should have received a copy of the GNU General Public License
  8606. +   along with this program; if not, write to the Free Software
  8607. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  8608. +   
  8609. +   Revision History:
  8610. +
  8611. +   14 jan 96: lkcl@pires.co.uk
  8612. +   added multiple workgroup domain master support
  8613. +
  8614. +*/
  8615. +
  8616. +#include "includes.h"
  8617. +#include "loadparm.h"
  8618. +#include "localnet.h"
  8619. +
  8620. +#define TEST_CODE /* want to debug unknown browse packets */
  8621. +
  8622. +extern int DEBUGLEVEL;
  8623. +extern pstring scope;
  8624. +extern BOOL CanRecurse;
  8625. +
  8626. +extern struct in_addr myip;
  8627. +extern struct in_addr bcast_ip;
  8628. +extern struct in_addr Netmask;
  8629. +
  8630. +extern pstring myname;
  8631. +
  8632. +extern int ClientNMB;
  8633. +extern int ClientDGRAM;
  8634. +
  8635. +extern int workgroup_count; /* total number of workgroups we know about */
  8636. +
  8637. +/* this is our browse cache database */
  8638. +extern struct browse_cache_record *browserlist;
  8639. +
  8640. +/* this is our domain/workgroup/server database */
  8641. +extern struct domain_record *domainlist;
  8642. +
  8643. +/* machine comment for host announcements */
  8644. +extern  pstring ServerComment;
  8645. +
  8646. +extern int  updatecount;
  8647. +
  8648. +/* what server type are we currently */
  8649. +#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
  8650. +        SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX |\
  8651. +        SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
  8652. +
  8653. +/* backup request types: which servers are to be included */
  8654. +#define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
  8655. +#define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL   )
  8656. +
  8657. +extern time_t StartupTime;
  8658. +
  8659. +#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
  8660. +#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
  8661. +
  8662. +#define MSBROWSE "\001\002__MSBROWSE__\002"
  8663. +#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
  8664. +
  8665. +#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
  8666. +
  8667. +
  8668. +/****************************************************************************
  8669. +tell a server to become a backup browser
  8670. +state - 0x01 become backup instead of master
  8671. +      - 0x02 remove all entries in browse list and become non-master
  8672. +      - 0x04 stop master browser service altogether. NT ignores this 
  8673. +**************************************************************************/
  8674. +void reset_server(char *name, int state, struct in_addr ip)
  8675. +{
  8676. +    char outbuf[20];
  8677. +    char *p;
  8678. +
  8679. +    bzero(outbuf,sizeof(outbuf));
  8680. +    p = outbuf;
  8681. +
  8682. +    CVAL(p,0) = 14;    /* request reset browser state */
  8683. +    CVAL(p,2) = state; /* type of request */
  8684. +    p += 2;
  8685. +
  8686. +    send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  8687. +                   myname,name,0x20,0x1d,ip,myip);
  8688. +}
  8689. +
  8690. +/****************************************************************************
  8691. +tell a server to become a backup browser
  8692. +**************************************************************************/
  8693. +void tell_become_backup(void)
  8694. +{
  8695. +    struct domain_record *d;
  8696. +    for (d = domainlist; d; d = d->next)
  8697. +    {
  8698. +        struct work_record *work;
  8699. +        for (work = d->workgrouplist; work; work = work->next)
  8700. +        {
  8701. +            struct server_record *s;
  8702. +            int num_servers = 0;
  8703. +            int num_backups = 0;
  8704. +
  8705. +            for (s = work->serverlist; s; s = s->next)
  8706. +            {
  8707. +                if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
  8708. +
  8709. +                num_servers++;
  8710. +
  8711. +                if (strequal(myname, s->serv.name)) continue;
  8712. +
  8713. +                if (s->serv.type & SV_TYPE_BACKUP_BROWSER)
  8714. +                {
  8715. +                    num_backups++;
  8716. +                    continue;
  8717. +                }
  8718. +
  8719. +                if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
  8720. +
  8721. +                if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
  8722. +
  8723. +                DEBUG(3,("num servers: %d num backups: %d\n", 
  8724. +                     num_servers, num_backups));
  8725. +
  8726. +                /* make first server a backup server. thereafter make every
  8727. +                   tenth server a backup server */
  8728. +                if (num_backups != 0 && (num_servers+9) / num_backups > 10)
  8729. +                {
  8730. +                    continue;
  8731. +                }
  8732. +
  8733. +                DEBUG(3,("workgroup %s subnet %s: make backup: %s %8x \n", 
  8734. +                         work->work_group, inet_ntoa(d->bcast_ip),
  8735. +                         s->serv.name, s->serv.type));
  8736. +                                                               
  8737. +                /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
  8738. +                do_announce_request(s->serv.name, work->work_group,
  8739. +                                    11, 0x20, 0x1e, d->bcast_ip);
  8740. +            }
  8741. +        }
  8742. +    }
  8743. +}
  8744. +
  8745. +/****************************************************************************
  8746. +find a server responsible for a workgroup, and sync browse lists
  8747. +**************************************************************************/
  8748. +static BOOL sync_browse_entry(struct browse_cache_record *b)
  8749. +{                     
  8750. +    struct domain_record *d;
  8751. +    struct work_record *work;
  8752. +/*
  8753. +    if (!strequal(serv_name, b->name))
  8754. +    {
  8755. +        DEBUG(0, ("browser's netbios name (%s) does not match %s (%s)",
  8756. +                b->name, inet_ntoa(b->ip), serv_name));
  8757. +    }
  8758. +*/
  8759. +    if (!(d = find_domain(b->ip))) return False;
  8760. +    if (!(work = find_workgroupstruct(d, b->group, False))) return False;
  8761. +
  8762. +    sync_browse_lists(work,b->name,0x20,b->ip);
  8763. +    b->synced = True;
  8764. +    
  8765. +    return True;
  8766. +}
  8767. +
  8768. +
  8769. +/****************************************************************************
  8770. +search through browser list for an entry to sync with
  8771. +**************************************************************************/
  8772. +void do_browser_lists(void)
  8773. +{
  8774. +    struct browse_cache_record *b;
  8775. +    static time_t last = 0;
  8776. +    time_t t = time(NULL);
  8777. +
  8778. +    if (t-last < 4) return; /* don't do too many of these at once! */
  8779. +
  8780. +    last = t;
  8781. +
  8782. +    /* pick any entry in the list, preferably one whose time is up */
  8783. +    for (b = browserlist; b && b->next; b = b->next)
  8784. +    {
  8785. +        if (b->sync_time < t && b->synced == False) break;
  8786. +    }
  8787. +
  8788. +    if (!b || b->synced || sync_browse_entry(b))
  8789. +    {
  8790. +        /* leave entries (even ones already sync'd) for up to a minute.
  8791. +           this stops them getting re-sync'd too often */
  8792. +        expire_browse_cache(t - 60);
  8793. +    }
  8794. +}
  8795. +
  8796. +
  8797. +/****************************************************************************
  8798. +find a server responsible for a workgroup, and sync browse lists
  8799. +control ends up back here via response_name_query.
  8800. +**************************************************************************/
  8801. +void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, int name_type,
  8802. +         struct in_addr ip)
  8803. +{                     
  8804. +    add_browser_entry(serv_name, name_type, work_name, 0, ip);
  8805. +
  8806. +    if (cmd == MASTER_SERVER_CHECK)
  8807. +    {
  8808. +        /* announce ourselves as a master browser to serv_name */
  8809. +        do_announce_request(myname, serv_name, 13, 0x20, 0, ip);
  8810. +    }
  8811. +}
  8812. +
  8813. +
  8814. +/****************************************************************************
  8815. +update workgroup database from a name registration
  8816. +**************************************************************************/
  8817. +void update_from_reg(char *name, int type, struct in_addr ip)
  8818. +{                     
  8819. +  /* default server type: minimum guess at requirement XXXX */
  8820. +
  8821. +  DEBUG(4,("update from registration: host %s ip %s type %0x\n",
  8822. +        name, inet_ntoa(ip), type));
  8823. +
  8824. +  /* workgroup types, but not a chat type */
  8825. +  if (type >= 0x1b && type <= 0x1e)
  8826. +    {
  8827. +      struct work_record *work;
  8828. +      struct domain_record *d;
  8829. +      
  8830. +      if (!(d    = find_domain(ip))) return;
  8831. +      if (!(work = find_workgroupstruct(d, name, False))) return;
  8832. +      
  8833. +      /* request the server to announce if on our subnet */
  8834. +      if (ip_equal(bcast_ip, d->bcast_ip)) announce_request(work, ip);
  8835. +      
  8836. +      /* domain master type or master browser type */
  8837. +      if (type == 0x1b || type == 0x1d)
  8838. +    {
  8839. +      struct hostent *hp = gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
  8840. +      if (hp) {
  8841. +        /* gethostbyaddr name may not match netbios name but who cares */
  8842. +        add_browser_entry(hp->h_name, type, work->work_group, 120, ip);
  8843. +      }
  8844. +    }
  8845. +    }
  8846. +}
  8847. +
  8848. +
  8849. +/****************************************************************************
  8850. +  add the default workgroup into my domain
  8851. +  **************************************************************************/
  8852. +void add_my_domains(void)
  8853. +{
  8854. +  /* add or find domain on our local subnet, in the default workgroup */
  8855. +  
  8856. +  if (*lp_workgroup() != '*')
  8857. +    {
  8858. +      add_domain_entry(bcast_ip,Netmask,lp_workgroup(), True);
  8859. +    }
  8860. +}
  8861. +
  8862. +
  8863. +/****************************************************************************
  8864. +  send a backup list response.
  8865. +  **************************************************************************/
  8866. +static void send_backup_list(char *work_name, struct nmb_name *src_name,
  8867. +                 int info_count, int token, int info,
  8868. +                 int name_type, struct in_addr ip)
  8869. +{                     
  8870. +  struct domain_record *d;
  8871. +  char outbuf[1024];
  8872. +  char *p, *countptr, *nameptr;
  8873. +  int count = 0;
  8874. +  int i, j;
  8875. +  char *theirname = src_name->name;
  8876. +  
  8877. +  DEBUG(3,("Backup list of %s to %s: %s(%x) %s(%x)\n", 
  8878. +       work_name, inet_ntoa(ip),
  8879. +       myname,0x20,theirname,0x0));       
  8880. +  
  8881. +  if (name_type == 0x1d)
  8882. +    {
  8883. +      DEBUG(4,("master browsers: "));
  8884. +    }
  8885. +  else if (name_type == 0x1b)
  8886. +    {
  8887. +      DEBUG(4,("domain controllers: "));
  8888. +    }
  8889. +  else
  8890. +    {
  8891. +      DEBUG(0,("backup request for unknown type %0x\n", name_type));
  8892. +      return;
  8893. +    }
  8894. +  
  8895. +  bzero(outbuf,sizeof(outbuf));
  8896. +  p = outbuf;
  8897. +  
  8898. +  CVAL(p,0) = 10;    /* backup list response */
  8899. +  p++;
  8900. +  
  8901. +  countptr = p; /* count pointer */
  8902. +  
  8903. +  SSVAL(p,1,token); /* sender's workgroup index representation */
  8904. +  SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
  8905. +  p += 5;
  8906. +  
  8907. +  nameptr = p;
  8908. +  
  8909. +  for (d = domainlist; d; d = d->next)
  8910. +    {
  8911. +      struct work_record *work;
  8912. +      
  8913. +      for (work = d->workgrouplist; work; work = work->next)
  8914. +    {
  8915. +      struct server_record *s;
  8916. +      
  8917. +      if (!strequal(work->work_group, work_name)) continue;
  8918. +      
  8919. +      for (s = work->serverlist; s; s = s->next)
  8920. +        { 
  8921. +          BOOL found = False;
  8922. +          char *n;
  8923. +          
  8924. +          if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
  8925. +          
  8926. +          for (n = nameptr; n < p; n = skip_string(n, 1))
  8927. +        {
  8928. +          if (strequal(n, s->serv.name)) found = True;
  8929. +        }
  8930. +          
  8931. +          if (found) continue; /* exclude names already added */
  8932. +          
  8933. +          /* workgroup request: include all backup browsers in the list */
  8934. +          /* domain request: include all domain members in the list */
  8935. +          
  8936. +          if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
  8937. +          (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
  8938. +        {                          
  8939. +          DEBUG(4, ("%s ", s->serv.name));
  8940. +          
  8941. +          count++;
  8942. +          strcpy(p,s->serv.name);
  8943. +          strupper(p);
  8944. +          p = skip_string(p,1);
  8945. +        }
  8946. +        }
  8947. +    }
  8948. +    }
  8949. +  
  8950. +  if (count == 0)
  8951. +    {
  8952. +      DEBUG(4, ("none\n"));
  8953. +      return;
  8954. +    }
  8955. +  else
  8956. +    {
  8957. +      DEBUG(4, (" - count %d\n", count));
  8958. +    }
  8959. +  
  8960. +  CVAL(countptr,0) = count; /* total number of backup browsers found */
  8961. +  
  8962. +  {
  8963. +    int len = PTR_DIFF(p, outbuf);
  8964. +    
  8965. +    for (i = 0; i < len; i+= 16)
  8966. +      {
  8967. +    DEBUG(4, ("%3x char ", i));
  8968. +    
  8969. +    for (j = 0; j < 16; j++)
  8970. +      {
  8971. +        unsigned char x = outbuf[i+j];
  8972. +        if (x < 32 || x > 127) x = '.';
  8973. +        
  8974. +        if (i+j >= len) break;
  8975. +        DEBUG(4, ("%c", x));
  8976. +      }
  8977. +    
  8978. +    DEBUG(4, (" hex ", i));
  8979. +    
  8980. +    for (j = 0; j < 16; j++)
  8981. +      {
  8982. +        if (i+j >= len) break;
  8983. +        DEBUG(4, (" %02x", outbuf[i+j]));
  8984. +      }
  8985. +    
  8986. +    DEBUG(4, ("\n"));
  8987. +      }
  8988. +    
  8989. +  }
  8990. +  send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
  8991. +              myname,theirname,0x20,0,ip,myip);
  8992. +}
  8993. +
  8994. +
  8995. +/*******************************************************************
  8996. +  same context: scope. should check name_type as well, and makes sure
  8997. +  we don't process messages from ourselves
  8998. +  ******************************************************************/
  8999. +BOOL same_context(struct dgram_packet *dgram)
  9000. +{
  9001. +  if (!strequal(dgram->dest_name  .scope,scope )) return(True);
  9002. +  if ( strequal(dgram->source_name.name ,myname)) return(True);
  9003. +  
  9004. +  return(False);
  9005. +}
  9006. +
  9007. +
  9008. +/*******************************************************************
  9009. +  am I listening on a name. XXXX check the type of name as well.
  9010. +  ******************************************************************/
  9011. +BOOL listening_name(struct work_record *work, struct nmb_name *n)
  9012. +{
  9013. +  if (strequal(n->name,myname) ||
  9014. +      strequal(n->name,work->work_group) ||
  9015. +      strequal(n->name,MSBROWSE))
  9016. +    {
  9017. +      return(True);
  9018. +    }
  9019. +  
  9020. +  return(False);
  9021. +}
  9022. +
  9023. +
  9024. +/*******************************************************************
  9025. +  process a domain announcement frame
  9026. +
  9027. +  Announce frames come in 3 types. Servers send host announcements
  9028. +  (command=1) to let the master browswer know they are
  9029. +  available. Master browsers send local master announcements
  9030. +  (command=15) to let other masters and backups that they are the
  9031. +  master. They also send domain announcements (command=12) to register
  9032. +  the domain
  9033. +
  9034. +  The comment field of domain announcements contains the master
  9035. +  browser name. The servertype is used by NetServerEnum to select
  9036. +  resources. We just have to pass it to smbd (via browser.dat) and let
  9037. +  the client choose using bit masks.
  9038. +  ******************************************************************/
  9039. +static void process_announce(struct packet_struct *p,int command,char *buf)
  9040. +{
  9041. +  struct dgram_packet *dgram = &p->packet.dgram;
  9042. +  struct in_addr ip = dgram->header.source_ip;
  9043. +  struct domain_record *d = find_domain(ip);
  9044. +  
  9045. +  int update_count = CVAL(buf,0);
  9046. +  int ttl = IVAL(buf,1)/1000;
  9047. +  char *name = buf+5;
  9048. +  int osmajor=CVAL(buf,21);
  9049. +  int osminor=CVAL(buf,22);
  9050. +  uint32 servertype = IVAL(buf,23);
  9051. +  char *comment = buf+31;
  9052. +  struct work_record *work;
  9053. +  char *work_name;
  9054. +  char *serv_name = dgram->source_name.name;
  9055. +  
  9056. +  comment[43] = 0;
  9057. +  
  9058. +  DEBUG(3,("Announce(%d) %s(%x)",command,name,name[15]));
  9059. +  DEBUG(3,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
  9060. +       namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
  9061. +       servertype,comment));
  9062. +  
  9063. +  name[15] = 0;  
  9064. +  
  9065. +  if (dgram->dest_name.name_type == 0 && command == 1)
  9066. +    {
  9067. +      DEBUG(2,("Announce to nametype(0) not supported yet\n"));
  9068. +      return;
  9069. +    }
  9070. +  if (command == 12 && ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
  9071. +            dgram->dest_name.name_type != 0x1))
  9072. +    {
  9073. +      DEBUG(0, ("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
  9074. +        command, inet_ntoa(ip), namestr(&dgram->dest_name)));
  9075. +      return;
  9076. +    }
  9077. +  
  9078. +  if (same_context(dgram)) return;
  9079. +  
  9080. +  if (command == 12)
  9081. +    {
  9082. +      work_name = name;
  9083. +    }
  9084. +  else
  9085. +    {
  9086. +      work_name = dgram->dest_name.name;
  9087. +    }
  9088. +  
  9089. +  if (!(work = find_workgroupstruct(d, work_name, False))) return;
  9090. +  
  9091. +  DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
  9092. +  
  9093. +  ttl = GET_TTL(ttl);
  9094. +  
  9095. +  /* add them to our browse list */
  9096. +  add_server_entry(d,work,name,servertype,ttl,comment,True);
  9097. +  
  9098. +  /* make a selection of machines become backup browsers (1 in 10) */
  9099. +  tell_become_backup();
  9100. +  
  9101. +  /* get their browse list from them and add it to ours. */
  9102. +  add_browser_entry(serv_name,dgram->dest_name.name_type,
  9103. +            work->work_group,30,ip);
  9104. +}
  9105. +
  9106. +/*******************************************************************
  9107. +  process a master announcement frame
  9108. +  ******************************************************************/
  9109. +static void process_master_announce(struct packet_struct *p,char *buf)
  9110. +{
  9111. +  struct dgram_packet *dgram = &p->packet.dgram;
  9112. +  struct in_addr ip = dgram->header.source_ip;
  9113. +  struct domain_record *d = find_domain(ip);
  9114. +  struct domain_record *mydomain = find_domain(bcast_ip);
  9115. +  char *name = buf;
  9116. +  struct work_record *work;
  9117. +  name[15] = 0;
  9118. +  
  9119. +  DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(ip)));
  9120. +  
  9121. +  if (same_context(dgram)) return;
  9122. +  
  9123. +  if (!d || !mydomain) return;
  9124. +  
  9125. +  if (!lp_domain_master()) return;
  9126. +  
  9127. +  for (work = mydomain->workgrouplist; work; work = work->next)
  9128. +    {
  9129. +      if (AM_MASTER(work))
  9130. +    {
  9131. +      /* merge browse lists with them */
  9132. +      add_browser_entry(name,0x1b, work->work_group,30,ip);
  9133. +    }
  9134. +    }
  9135. +}
  9136. +
  9137. +/*******************************************************************
  9138. +  process a receive backup list request
  9139. +  
  9140. +  we receive a list of servers, and we attempt to locate them all on
  9141. +  our local subnet, and sync browse lists with them on the workgroup
  9142. +  they are said to be in.
  9143. +  ******************************************************************/
  9144. +static void process_rcv_backup_list(struct packet_struct *p,char *buf)
  9145. +{
  9146. +  struct dgram_packet *dgram = &p->packet.dgram;
  9147. +  struct in_addr ip = dgram->header.source_ip;
  9148. +  int count = CVAL(buf,0);
  9149. +  int Index = IVAL(buf,1); /* caller's index representing workgroup */
  9150. +  char *buf1;
  9151. +  
  9152. +  DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
  9153. +       namestr(&dgram->dest_name), inet_ntoa(ip),
  9154. +       count, Index));
  9155. +  
  9156. +  if (same_context(dgram)) return;
  9157. +  
  9158. +  if (count <= 0) return;
  9159. +  
  9160. +  /* go through the list of servers attempting to sync browse lists */
  9161. +  for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
  9162. +    {
  9163. +      struct in_addr back_ip;
  9164. +      struct domain_record *d;
  9165. +      
  9166. +      DEBUG(4, ("Searching for backup browser %s at %s...\n",
  9167. +        buf1, inet_ntoa(ip)));
  9168. +      
  9169. +      /* XXXX assume name is a DNS name NOT a netbios name. a more complete
  9170. +     approach is to use reply_name_query functionality to find the name */
  9171. +      back_ip = *interpret_addr2(buf1);
  9172. +      
  9173. +      if (zero_ip(back_ip))
  9174. +    {
  9175. +      DEBUG(4,("Failed to find backup browser server using DNS\n"));
  9176. +      continue;
  9177. +    }
  9178. +      
  9179. +      DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
  9180. +      
  9181. +      if ((d = find_domain(back_ip)))
  9182. +    {
  9183. +      struct domain_record *d1;
  9184. +      for (d1 = domainlist; d1; d1 = d1->next)
  9185. +        {
  9186. +          struct work_record *work;
  9187. +          for (work = d1->workgrouplist; work; work = work->next)
  9188. +        {
  9189. +          if (work->token == Index)
  9190. +            {
  9191. +              queue_netbios_packet(ClientNMB,NMB_QUERY,SERVER_CHECK,
  9192. +                       work->work_group,0x1d,0,
  9193. +                       False,False,back_ip);
  9194. +              return;
  9195. +            }
  9196. +        }
  9197. +        }
  9198. +    }
  9199. +    }
  9200. +}
  9201. +
  9202. +/*******************************************************************
  9203. +  process a send backup list request
  9204. +
  9205. +  A client send a backup list request to ask for a list of servers on
  9206. +  the net that maintain server lists for a domain. A server is then
  9207. +  chosen from this list to send NetServerEnum commands to to list
  9208. +  available servers.
  9209. +
  9210. +  Currently samba only sends back one name in the backup list, its
  9211. +  own. For larger nets we'll have to add backups and send "become
  9212. +  backup" requests occasionally.
  9213. +  ******************************************************************/
  9214. +static void process_send_backup_list(struct packet_struct *p,char *buf)
  9215. +{
  9216. +  struct dgram_packet *dgram = &p->packet.dgram;
  9217. +  struct in_addr ip = dgram->header.source_ip;
  9218. +  struct domain_record *d; /* = find_domain(ip); */
  9219. +  struct work_record *work;
  9220. +
  9221. +  int count = CVAL(buf,0);
  9222. +  int token = SVAL(buf,1); /* sender's key index for the workgroup? */
  9223. +  int info  = SVAL(buf,3); /* XXXX don't know: some sort of info */
  9224. +  int name_type = dgram->dest_name.name_type;
  9225. +
  9226. +  DEBUG(0,("Send Backup request to %s token=%d info = %x count=%d\n",
  9227. +       namestr(&dgram->dest_name), token, info, count));
  9228. +  
  9229. +  if (same_context(dgram)) return;
  9230. +  
  9231. +  if (count <= 0) return;
  9232. +  
  9233. +  if (name_type != 0x1b && name_type != 0x1d)
  9234. +    {
  9235. +      DEBUG(0, ("backup request to wrong type %d\n", name_type));
  9236. +      return;
  9237. +    }
  9238. +  
  9239. +  for (d = domainlist; d; d = d->next)
  9240. +    {
  9241. +      for (work = d->workgrouplist; work; work = work->next)
  9242. +    {
  9243. +      if (strequal(work->work_group, dgram->dest_name.name))
  9244. +        {
  9245. +          DEBUG(3, ("found workgroup %s(%d)\n",
  9246. +            work->work_group, work->token));
  9247. +          send_backup_list(work->work_group,&dgram->source_name,
  9248. +                   count,token,info,name_type,ip);
  9249. +          return;
  9250. +        }
  9251. +    } 
  9252. +    }
  9253. +}
  9254. +
  9255. +
  9256. +/*******************************************************************
  9257. +  process a reset browser state
  9258. +
  9259. +  diagnostic packet:
  9260. +  0x1 - stop being a master browser
  9261. +  0x2 - discard browse lists, stop being a master browser, try again.
  9262. +  0x4 - stop being a master browser forever. no way. ain't gonna.
  9263. +         
  9264. +  ******************************************************************/
  9265. +static void process_reset_browser(struct packet_struct *p,char *buf)
  9266. +{
  9267. +  struct dgram_packet *dgram = &p->packet.dgram;
  9268. +  int state = CVAL(buf,0);
  9269. +
  9270. +  DEBUG(1,("Diagnostic browser reset request to %s state=0x%X\n",
  9271. +       namestr(&dgram->dest_name), state));
  9272. +
  9273. +  /* stop being a master but still deal with being a backup browser */
  9274. +  if (state & 0x1)
  9275. +    {
  9276. +      struct domain_record *d;
  9277. +      for (d = domainlist; d; d = d->next)
  9278. +    {
  9279. +      struct work_record *work;
  9280. +      for (work = d->workgrouplist; work; work = work->next)
  9281. +        {
  9282. +          if (AM_MASTER(work))
  9283. +        {
  9284. +          become_nonmaster(d,work);
  9285. +        }
  9286. +        }
  9287. +    }
  9288. +    }
  9289. +  
  9290. +  /* totally delete all servers and start afresh */
  9291. +  if (state & 0x2)
  9292. +    {
  9293. +      struct domain_record *d;
  9294. +      for (d = domainlist; d; d = d->next)
  9295. +    {
  9296. +      struct work_record *work;
  9297. +      for (work=d->workgrouplist;work;work=remove_workgroup(d,work));
  9298. +    }
  9299. +      add_my_domains();
  9300. +    }
  9301. +  
  9302. +  /* stop browsing altogether. i don't think this is a good idea! */
  9303. +  if (state & 0x4)
  9304. +    {
  9305. +      DEBUG(1, ("ignoring request to stop being a browser. sorry!\n"));
  9306. +    }
  9307. +}
  9308. +
  9309. +
  9310. +/*******************************************************************
  9311. +  process a announcement request
  9312. +
  9313. +  clients send these when they want everyone to send an announcement
  9314. +  immediately. This can cause quite a storm of packets!
  9315. +  ******************************************************************/
  9316. +static void process_announce_request(struct packet_struct *p,char *buf)
  9317. +{
  9318. +  struct dgram_packet *dgram = &p->packet.dgram;
  9319. +  struct work_record *work;
  9320. +  struct in_addr ip = dgram->header.source_ip;
  9321. +  struct domain_record *d = find_domain(ip);
  9322. +  int token = CVAL(buf,0);
  9323. +  char *name = buf+1;
  9324. +  
  9325. +  name[15] = 0;
  9326. +  
  9327. +  DEBUG(3,("Announce request from %s to %s token=0x%X\n",
  9328. +       name,namestr(&dgram->dest_name), token));
  9329. +  
  9330. +  if (strequal(dgram->source_name.name,myname)) return;
  9331. +  
  9332. +  if (!d) return;
  9333. +  
  9334. +  if (!ip_equal(bcast_ip, d->bcast_ip)) return;
  9335. +  
  9336. +  for (work = d->workgrouplist; work; work = work->next)
  9337. +    {
  9338. +      if (strequal(dgram->dest_name.name,work->work_group)) 
  9339. +    {
  9340. +      work->needannounce = True;
  9341. +    }
  9342. +    }
  9343. +}
  9344. +
  9345. +
  9346. +/****************************************************************************
  9347. +   process a domain logon packet
  9348. +   **************************************************************************/
  9349. +void process_logon_packet(struct packet_struct *p,char *buf,int len)
  9350. +{
  9351. +  struct dgram_packet *dgram = &p->packet.dgram;
  9352. +  struct in_addr ip = dgram->header.source_ip;
  9353. +  struct domain_record *d = find_domain(ip);
  9354. +  char *logname,*q;
  9355. +  char *reply_name;
  9356. +  BOOL add_slashes = False;
  9357. +  pstring outbuf;
  9358. +  int code,reply_code;
  9359. +  struct work_record *work;
  9360. +  
  9361. +  if (!d) return;
  9362. +  
  9363. +  if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) 
  9364. +    return;
  9365. +  
  9366. +  if (!lp_domain_logons()) {
  9367. +    DEBUG(3,("No domain logons\n"));
  9368. +    return;
  9369. +  }
  9370. +  if (!listening_name(work, &dgram->dest_name))
  9371. +    {
  9372. +      DEBUG(4,("Not listening to that domain\n"));
  9373. +      return;
  9374. +    }
  9375. +  
  9376. +  code = SVAL(buf,0);
  9377. +  switch (code) {
  9378. +  case 0:    
  9379. +    {
  9380. +      char *machine = buf+2;
  9381. +      char *user = skip_string(machine,1);
  9382. +      logname = skip_string(user,1);
  9383. +      reply_code = 6;
  9384. +      reply_name = myname;
  9385. +      add_slashes = True;
  9386. +      DEBUG(3,("Domain login request from %s(%s) user=%s\n",
  9387. +            machine,inet_ntoa(p->ip),user));
  9388. +    }
  9389. +    break;
  9390. +  case 7:    
  9391. +    {
  9392. +      char *machine = buf+2;
  9393. +      logname = skip_string(machine,1);
  9394. +      reply_code = 7;
  9395. +      reply_name = lp_domain_controller();
  9396. +      if (!*reply_name) {
  9397. +     DEBUG(3,("No domain controller configured\n"));
  9398. +     return;
  9399. +      }
  9400. +      DEBUG(3,("GETDC request from %s(%s)\n",
  9401. +            machine,inet_ntoa(p->ip)));
  9402. +    }
  9403. +    break;
  9404. +  default:
  9405. +    DEBUG(3,("Unknown domain request %d\n",code));
  9406. +    return;
  9407. +  }
  9408. +  
  9409. +  bzero(outbuf,sizeof(outbuf));
  9410. +  q = outbuf;
  9411. +  SSVAL(q,0,reply_code);
  9412. +  q += 2;
  9413. +  if (add_slashes) {
  9414. +    strcpy(q,"\\\\");
  9415. +    q += 2;
  9416. +  }
  9417. +  StrnCpy(q,reply_name,16);
  9418. +  strupper(q);
  9419. +  q = skip_string(q,1);
  9420. +  SSVAL(q,0,0xFFFF);
  9421. +  q += 2;
  9422. +  
  9423. +  send_mailslot_reply(logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
  9424. +               myname,&dgram->source_name.name[0],0x20,0,p->ip,myip);  
  9425. + }
  9426. +
  9427. +/****************************************************************************
  9428. +depending on what announce has been made, we are only going to
  9429. +accept certain types of name announce. XXXX untested code
  9430. +
  9431. +check listening name type
  9432. +****************************************************************************/
  9433. +BOOL listening_type(struct packet_struct *p, int command)
  9434. +{
  9435. +  struct dgram_packet *dgram = &p->packet.dgram;
  9436. +  int type = dgram->dest_name.name_type;
  9437. +
  9438. +  switch (command)
  9439. +    {
  9440. +    case 1: /* host announce */
  9441. +      {
  9442. +    if (type != 0x0 || type != 0x20) return (False);
  9443. +    break;
  9444. +      }
  9445. +      
  9446. +    case 2: /* announce request */
  9447. +      {
  9448. +    return (True);
  9449. +    break;
  9450. +      }
  9451. +      
  9452. +    case 8: /* election */
  9453. +      {
  9454. +    return (True);
  9455. +    break;
  9456. +      }
  9457. +      
  9458. +    case 9: /* get backup list */
  9459. +      {
  9460. +    return (True);
  9461. +    break;
  9462. +      }
  9463. +      
  9464. +    case 10: /* receive backup list */
  9465. +      {
  9466. +    return (True);
  9467. +    break;
  9468. +      }
  9469. +      
  9470. +    case 12: /* domain announce */
  9471. +      {
  9472. +    if (type != 0x1b || type != 0x1c) return (False);
  9473. +    break;
  9474. +      }
  9475. +      
  9476. +    case 13: /* master announcement */
  9477. +      {
  9478. +    if (type != 0x1d) return (False);
  9479. +    break;
  9480. +      }
  9481. +      
  9482. +    case 15: /* local master announce */
  9483. +      {
  9484. +    if (type != 0x1c || type != 0x1d) return (False);
  9485. +    break;
  9486. +      }
  9487. +    }
  9488. +  return (True); /* we're not dealing with unknown packet types */
  9489. +}
  9490. +
  9491. +
  9492. +/****************************************************************************
  9493. +process a browse frame
  9494. +****************************************************************************/
  9495. +void process_browse_packet(struct packet_struct *p,char *buf,int len)
  9496. +{
  9497. +  int command = CVAL(buf,0);
  9498. +  switch (command) 
  9499. +    {
  9500. +    case 1: /* host announce */
  9501. +    case 12: /* domain announce */
  9502. +    case 15: /* local master announce */
  9503. +      {
  9504. +    process_announce(p,command,buf+1);
  9505. +    break;
  9506. +      }
  9507. +      
  9508. +    case 2: /* announce request */
  9509. +      {
  9510. +    process_announce_request(p,buf+1);
  9511. +    break;
  9512. +      }
  9513. +      
  9514. +    case 8: /* election */
  9515. +      {
  9516. +    process_election(p,buf+1);
  9517. +    break;
  9518. +      }
  9519. +      
  9520. +    case 9: /* get backup list */
  9521. +      {
  9522. +    process_send_backup_list(p,buf+1);
  9523. +    break;
  9524. +      }
  9525. +      
  9526. +    case 10: /* receive backup list */
  9527. +      {
  9528. +#ifdef TEST_CODE
  9529. +    struct dgram_packet *dgram = &p->packet.dgram;
  9530. +    int i, j;
  9531. +    
  9532. +    DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
  9533. +          command, namestr(&dgram->source_name), 
  9534. +          inet_ntoa(p->ip), namestr(&dgram->dest_name)));
  9535. +    
  9536. +    for (i = 0; i < len; i+= 16)
  9537. +      {
  9538. +        DEBUG(4, ("%3x char ", i));
  9539. +        
  9540. +        for (j = 0; j < 16; j++)
  9541. +          {
  9542. +        unsigned char x = buf[i+j];
  9543. +        if (x < 32 || x > 127) x = '.';
  9544. +        
  9545. +        if (i+j >= len) break;
  9546. +        DEBUG(4, ("%c", x));
  9547. +          }
  9548. +        
  9549. +        DEBUG(4, (" hex ", i));
  9550. +        
  9551. +        for (j = 0; j < 16; j++)
  9552. +          {
  9553. +        if (i+j >= len) break;
  9554. +        DEBUG(4, (" %02x", buf[i+j]));
  9555. +          }
  9556. +        
  9557. +        DEBUG(4, ("\n"));
  9558. +      }
  9559. +    
  9560. +#endif /* TEST_CODE */
  9561. +    process_rcv_backup_list(p, buf+1);
  9562. +    break;
  9563. +      }
  9564. +      
  9565. +    case 11: /* reset browser state */
  9566. +      {
  9567. +    process_reset_browser(p, buf+1);
  9568. +    break;
  9569. +      }
  9570. +      
  9571. +    case 13: /* master announcement */
  9572. +      {
  9573. +    process_master_announce(p,buf+1);
  9574. +    break;
  9575. +      }
  9576. +      
  9577. +#ifdef TEST_CODE
  9578. +    default:
  9579. +      {
  9580. +    struct dgram_packet *dgram = &p->packet.dgram;
  9581. +    int i, j;
  9582. +    
  9583. +    DEBUG(4, ("ignoring browse packet %d from %s %s to %s\n",
  9584. +          command, namestr(&dgram->source_name), 
  9585. +          inet_ntoa(p->ip), namestr(&dgram->dest_name)));
  9586. +    
  9587. +    for (i = 0; i < len; i+= 16)
  9588. +      {
  9589. +        DEBUG(4, ("%3x char ", i));
  9590. +        
  9591. +        for (j = 0; j < 16; j++)
  9592. +          {
  9593. +        unsigned char x = buf[i+j];
  9594. +        if (x < 32 || x > 127) x = '.';
  9595. +        
  9596. +        if (i+j >= len) break;
  9597. +        DEBUG(4, ("%c", x));
  9598. +          }
  9599. +        
  9600. +        DEBUG(4, (" hex ", i));
  9601. +        
  9602. +        for (j = 0; j < 16; j++)
  9603. +          {
  9604. +        if (i+j >= len) break;
  9605. +        DEBUG(4, (" %02x", buf[i+j]));
  9606. +          }
  9607. +        
  9608. +        DEBUG(4, ("\n"));
  9609. +      }
  9610. +    
  9611. +      }
  9612. +#endif /* TEST_CODE */
  9613. +    }
  9614. +}
  9615. +
  9616. +
  9617. +/****************************************************************************
  9618. +process udp 138 datagrams
  9619. +****************************************************************************/
  9620. +void process_dgram(struct packet_struct *p)
  9621. +{
  9622. +  char *buf;
  9623. +  char *buf2;
  9624. +  int len;
  9625. +  struct dgram_packet *dgram = &p->packet.dgram;
  9626. +
  9627. +  if (dgram->header.msg_type != 0x10 &&
  9628. +      dgram->header.msg_type != 0x11 &&
  9629. +      dgram->header.msg_type != 0x12) {
  9630. +    /* don't process error packets etc yet */
  9631. +    return;
  9632. +  }
  9633. +
  9634. +  buf = &dgram->data[0];
  9635. +  buf -= 4; /* XXXX for the pseudo tcp length - 
  9636. +           someday I need to get rid of this */
  9637. +
  9638. +  if (CVAL(buf,smb_com) != SMBtrans) return;
  9639. +
  9640. +  len = SVAL(buf,smb_vwv11);
  9641. +  buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
  9642. +
  9643. +  DEBUG(3,("datagram from %s to %s for %s of type %d len=%d\n",
  9644. +       namestr(&dgram->source_name),namestr(&dgram->dest_name),
  9645. +       smb_buf(buf),CVAL(buf2,0),len));
  9646. +
  9647. +  if (len <= 0) return;
  9648. +
  9649. +   if (strequal(smb_buf(buf),"\\MAILSLOT\\BROWSE"))
  9650. +   {
  9651. +     process_browse_packet(p,buf2,len);
  9652. +   } else if (strequal(smb_buf(buf),"\\MAILSLOT\\NET\\NETLOGON")) {
  9653. +     process_logon_packet(p,buf2,len);
  9654. +   }
  9655. +}
  9656. +
  9657. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nmbd.c samba-1.9.16alpha5/source/nmbd.c
  9658. --- samba-1.9.16alpha4/source/nmbd.c    Thu Jan  1 10:00:00 1970
  9659. +++ samba-1.9.16alpha5/source/nmbd.c    Wed Jun  5 01:14:26 1996
  9660. @@ -0,0 +1,603 @@
  9661. +/*
  9662. +   Unix SMB/Netbios implementation.
  9663. +   Version 1.9.
  9664. +   NBT netbios routines and daemon - version 2
  9665. +   Copyright (C) Andrew Tridgell 1994-1995
  9666. +   
  9667. +   This program is free software; you can redistribute it and/or modify
  9668. +   it under the terms of the GNU General Public License as published by
  9669. +   the Free Software Foundation; either version 2 of the License, or
  9670. +   (at your option) any later version.
  9671. +   
  9672. +   This program is distributed in the hope that it will be useful,
  9673. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  9674. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9675. +   GNU General Public License for more details.
  9676. +   
  9677. +   You should have received a copy of the GNU General Public License
  9678. +   along with this program; if not, write to the Free Software
  9679. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  9680. +   
  9681. +   Revision History:
  9682. +
  9683. +   14 jan 96: lkcl@pires.co.uk
  9684. +   added multiple workgroup domain master support
  9685. +
  9686. +*/
  9687. +
  9688. +#include "includes.h"
  9689. +#include "loadparm.h"
  9690. +#include "localnet.h"
  9691. +
  9692. +extern int DEBUGLEVEL;
  9693. +
  9694. +extern pstring debugf;
  9695. +pstring servicesf = CONFIGFILE;
  9696. +
  9697. +extern pstring scope;
  9698. +
  9699. +int ClientNMB   = -1;
  9700. +int ClientDGRAM = -1;
  9701. +
  9702. +extern pstring myhostname;
  9703. +static pstring host_file;
  9704. +extern pstring myname;
  9705. +
  9706. +/* are we running as a daemon ? */
  9707. +static BOOL is_daemon = False;
  9708. +
  9709. +/* machine comment for host announcements */
  9710. +pstring ServerComment="";
  9711. +
  9712. +static BOOL got_bcast = False;
  9713. +static BOOL got_myip = False;
  9714. +static BOOL got_nmask = False;
  9715. +
  9716. +/* what server type are we currently */
  9717. +
  9718. +time_t StartupTime =0;
  9719. +
  9720. +struct in_addr ipzero;
  9721. +
  9722. +
  9723. +/****************************************************************************
  9724. +catch a sighup
  9725. +****************************************************************************/
  9726. +static int sig_hup(void)
  9727. +{
  9728. +  BlockSignals(True);
  9729. +
  9730. +  DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
  9731. +  dump_names();
  9732. +  reload_services(True);
  9733. +
  9734. +  BlockSignals(False);
  9735. +#ifndef DONT_REINSTALL_SIG
  9736. +  signal(SIGHUP,SIGNAL_CAST sig_hup);
  9737. +#endif
  9738. +  return(0);
  9739. +}
  9740. +
  9741. +/****************************************************************************
  9742. +catch a sigpipe
  9743. +****************************************************************************/
  9744. +static int sig_pipe(void)
  9745. +{
  9746. +  BlockSignals(True);
  9747. +
  9748. +  DEBUG(0,("Got SIGPIPE\n"));
  9749. +  if (!is_daemon)
  9750. +    exit(1);
  9751. +  BlockSignals(False);
  9752. +  return(0);
  9753. +}
  9754. +
  9755. +#if DUMP_CORE
  9756. +/*******************************************************************
  9757. +prepare to dump a core file - carefully!
  9758. +********************************************************************/
  9759. +static BOOL dump_core(void)
  9760. +{
  9761. +  char *p;
  9762. +  pstring dname;
  9763. +  strcpy(dname,debugf);
  9764. +  if ((p=strrchr(dname,'/'))) *p=0;
  9765. +  strcat(dname,"/corefiles");
  9766. +  mkdir(dname,0700);
  9767. +  sys_chown(dname,getuid(),getgid());
  9768. +  chmod(dname,0700);
  9769. +  if (chdir(dname)) return(False);
  9770. +  umask(~(0700));
  9771. +
  9772. +#ifndef NO_GETRLIMIT
  9773. +#ifdef RLIMIT_CORE
  9774. +  {
  9775. +    struct rlimit rlp;
  9776. +    getrlimit(RLIMIT_CORE, &rlp);
  9777. +    rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
  9778. +    setrlimit(RLIMIT_CORE, &rlp);
  9779. +    getrlimit(RLIMIT_CORE, &rlp);
  9780. +    DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
  9781. +  }
  9782. +#endif
  9783. +#endif
  9784. +
  9785. +
  9786. +  DEBUG(0,("Dumping core in %s\n",dname));
  9787. +  return(True);
  9788. +}
  9789. +#endif
  9790. +
  9791. +
  9792. +/****************************************************************************
  9793. +possibly continue after a fault
  9794. +****************************************************************************/
  9795. +static void fault_continue(void)
  9796. +{
  9797. +#if DUMP_CORE
  9798. +  dump_core();
  9799. +#endif
  9800. +}
  9801. +
  9802. +/*******************************************************************
  9803. +  expire old names from the namelist and server list
  9804. +  ******************************************************************/
  9805. +static void expire_names_and_servers(void)
  9806. +{
  9807. +  static time_t lastrun = 0;
  9808. +  time_t t = time(NULL);
  9809. +  
  9810. +  if (!lastrun) lastrun = t;
  9811. +  if (t < lastrun + 5) return;
  9812. +  lastrun = t;
  9813. +  
  9814. +  expire_names(t);
  9815. +  expire_servers(t);
  9816. +}
  9817. +
  9818. +/*****************************************************************************
  9819. +  reload the services file
  9820. +  **************************************************************************/
  9821. +BOOL reload_services(BOOL test)
  9822. +{
  9823. +  BOOL ret;
  9824. +  extern fstring remote_machine;
  9825. +
  9826. +  strcpy(remote_machine,"nmbd");
  9827. +
  9828. +  if (lp_loaded())
  9829. +    {
  9830. +      pstring fname;
  9831. +      strcpy(fname,lp_configfile());
  9832. +      if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
  9833. +    {
  9834. +      strcpy(servicesf,fname);
  9835. +      test = False;
  9836. +    }
  9837. +    }
  9838. +
  9839. +  if (test && !lp_file_list_changed())
  9840. +    return(True);
  9841. +
  9842. +  ret = lp_load(servicesf,True);
  9843. +
  9844. +  /* perhaps the config filename is now set */
  9845. +  if (!test) {
  9846. +    DEBUG(3,("services not loaded\n"));
  9847. +    reload_services(True);
  9848. +  }
  9849. +
  9850. +  return(ret);
  9851. +}
  9852. +
  9853. +
  9854. +
  9855. +/****************************************************************************
  9856. +load a netbios hosts file
  9857. +****************************************************************************/
  9858. +static void load_hosts_file(char *fname)
  9859. +{
  9860. +  FILE *f = fopen(fname,"r");
  9861. +  pstring line;
  9862. +  if (!f) {
  9863. +    DEBUG(2,("Can't open lmhosts file %s\n",fname));
  9864. +    return;
  9865. +  }
  9866. +
  9867. +  while (!feof(f))
  9868. +    {
  9869. +      if (!fgets_slash(line,sizeof(pstring),f)) continue;
  9870. +
  9871. +      if (*line == '#') continue;
  9872. +
  9873. +      {
  9874. +    BOOL group=False;
  9875. +
  9876. +    pstring ip,name,mask,flags,extra;
  9877. +
  9878. +    char *ptr;
  9879. +    int count = 0;
  9880. +    struct in_addr ipaddr;
  9881. +    struct in_addr ipmask;
  9882. +    enum name_source source = LMHOSTS;
  9883. +
  9884. +    strcpy(ip,"");
  9885. +    strcpy(name,"");
  9886. +    strcpy(mask,"");
  9887. +    strcpy(flags,"");
  9888. +    strcpy(extra,"");
  9889. +    
  9890. +    ptr = line;
  9891. +
  9892. +    if (next_token(&ptr,ip   ,NULL)) ++count;
  9893. +    if (next_token(&ptr,name ,NULL)) ++count;
  9894. +    if (next_token(&ptr,mask ,NULL)) ++count;
  9895. +    if (next_token(&ptr,flags,NULL)) ++count;
  9896. +    if (next_token(&ptr,extra,NULL)) ++count;
  9897. +
  9898. +    if (count <= 0) continue;
  9899. +
  9900. +    if (count > 0 && count < 2) {
  9901. +      DEBUG(0,("Ill formed hosts line [%s]\n",line));        
  9902. +      continue;
  9903. +    }
  9904. +
  9905. +    /* work out if we need to shuffle the tokens along due to the
  9906. +       optional subnet mask argument */
  9907. +
  9908. +    if (strchr(mask, 'G') || strchr(mask, 'S') || strchr(mask, 'M')) {
  9909. +      strcpy(flags, mask );
  9910. +      /* default action for no subnet mask */
  9911. +      strcpy(mask, inet_ntoa(Netmask));
  9912. +    }
  9913. +
  9914. +    DEBUG(4, ("lmhost entry: %s %s %s %s\n", ip, name, mask, flags));
  9915. +
  9916. +    if (strchr(flags,'G') || strchr(flags,'S'))
  9917. +      group = True;
  9918. +
  9919. +    if (strchr(flags,'M') && !group) {
  9920. +      source = SELF;
  9921. +      strcpy(myname,name);
  9922. +    }
  9923. +
  9924. +    ipaddr = *interpret_addr2(ip);
  9925. +    ipmask = *interpret_addr2(mask);
  9926. +
  9927. +    if (group) {
  9928. +      add_domain_entry(ipaddr, ipmask, name, True);
  9929. +    } else {
  9930. +      add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr);
  9931. +    }
  9932. +      }
  9933. +    }
  9934. +
  9935. +  fclose(f);
  9936. +}
  9937. +
  9938. +
  9939. +/****************************************************************************
  9940. +  The main select loop.
  9941. +  ***************************************************************************/
  9942. +static void process(void)
  9943. +{
  9944. +  BOOL run_election;
  9945. +
  9946. +  while (True)
  9947. +    {
  9948. +      time_t t = time(NULL);
  9949. +      run_election = check_elections();
  9950. +      listen_for_packets(run_election);
  9951. +
  9952. +      run_packet_queue();
  9953. +      run_elections();
  9954. +
  9955. +      announce_host();
  9956. +      announce_backup();
  9957. +      announce_master();
  9958. +
  9959. +      expire_names_and_servers();
  9960. +      expire_netbios_response_entries(t-10);
  9961. +      refresh_my_names(t);
  9962. +
  9963. +      write_browse_list();
  9964. +      do_browser_lists();
  9965. +      check_master_browser();
  9966. +    }
  9967. +}
  9968. +
  9969. +
  9970. +/****************************************************************************
  9971. +  open the socket communication
  9972. +****************************************************************************/
  9973. +static BOOL open_sockets(BOOL isdaemon, int port)
  9974. +{
  9975. +  struct hostent *hp;
  9976. +  /* get host info */
  9977. +  if ((hp = Get_Hostbyname(myhostname)) == 0) {
  9978. +    DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
  9979. +    return False;
  9980. +  }   
  9981. +
  9982. +  if (isdaemon)
  9983. +    ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
  9984. +  else
  9985. +    ClientNMB = 0;
  9986. +  
  9987. +  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
  9988. +
  9989. +  if (ClientNMB == -1)
  9990. +    return(False);
  9991. +
  9992. +  signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  9993. +
  9994. +  set_socket_options(ClientNMB,"SO_BROADCAST");
  9995. +  set_socket_options(ClientDGRAM,"SO_BROADCAST");
  9996. +
  9997. +  DEBUG(3,("Sockets opened.\n"));
  9998. +  return True;
  9999. +}
  10000. +
  10001. +
  10002. +/*******************************************************************
  10003. +  check that a IP, bcast and netmask and consistent. Must be a 1s
  10004. +  broadcast
  10005. +  ******************************************************************/
  10006. +static BOOL ip_consistent(struct in_addr ip,struct in_addr bcast, struct in_addr nmask)
  10007. +{
  10008. +  unsigned long a_ip,a_bcast,a_nmask;
  10009. +
  10010. +  a_ip = ntohl(ip.s_addr);
  10011. +  a_bcast = ntohl(bcast.s_addr);
  10012. +  a_nmask = ntohl(nmask.s_addr);
  10013. +
  10014. +  /* check the netmask is sane */
  10015. +  if (((a_nmask>>24)&0xFF) != 0xFF) {
  10016. +    DEBUG(0,("Insane netmask %s\n",inet_ntoa(nmask)));
  10017. +    return(False);
  10018. +  }
  10019. +
  10020. +  /* check the IP and bcast are on the same net */
  10021. +  if ((a_ip&a_nmask) != (a_bcast&a_nmask)) {
  10022. +    DEBUG(0,("IP and broadcast are on different nets!\n"));
  10023. +    return(False);
  10024. +  }
  10025. +
  10026. +  /* check the IP and bcast are on the same net */
  10027. +  if ((a_bcast|a_nmask) != 0xFFFFFFFF) {
  10028. +    DEBUG(0,("Not a ones based broadcast %s\n",inet_ntoa(bcast)));
  10029. +    return(False);
  10030. +  }
  10031. +
  10032. +  return(True);
  10033. +}
  10034. +
  10035. +
  10036. +/****************************************************************************
  10037. +  initialise connect, service and file structs
  10038. +****************************************************************************/
  10039. +static BOOL init_structs()
  10040. +{
  10041. +  if (!get_myname(myhostname,got_myip?NULL:&myip))
  10042. +    return(False);
  10043. +
  10044. +  /* Read the broadcast address from the interface */
  10045. +  {
  10046. +    struct in_addr ip0,ip1,ip2;
  10047. +
  10048. +    ip0 = myip;
  10049. +
  10050. +    if (!(got_bcast && got_nmask))
  10051. +      {
  10052. +    get_broadcast(&ip0,&ip1,&ip2);
  10053. +
  10054. +    if (!got_myip)
  10055. +      myip = ip0;
  10056. +    
  10057. +    if (!got_bcast)
  10058. +      bcast_ip = ip1;
  10059. +    
  10060. +    if (!got_nmask)
  10061. +      Netmask = ip2;   
  10062. +      } 
  10063. +
  10064. +    DEBUG(1,("Using IP %s  ",inet_ntoa(myip))); 
  10065. +    DEBUG(1,("broadcast %s  ",inet_ntoa(bcast_ip)));
  10066. +    DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));    
  10067. +
  10068. +    if (!ip_consistent(myip,bcast_ip,Netmask)) {
  10069. +      DEBUG(0,("WARNING: The IP address, broadcast and Netmask are not consistent\n"));
  10070. +      DEBUG(0,("You are likely to experience problems with this setup!\n"));
  10071. +    }
  10072. +  }
  10073. +
  10074. +  if (! *myname) {
  10075. +    char *p;
  10076. +    strcpy(myname,myhostname);
  10077. +    p = strchr(myname,'.');
  10078. +    if (p) *p = 0;
  10079. +  }
  10080. +
  10081. +  return True;
  10082. +}
  10083. +
  10084. +/****************************************************************************
  10085. +usage on the program
  10086. +****************************************************************************/
  10087. +static void usage(char *pname)
  10088. +{
  10089. +  DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
  10090. +
  10091. +  printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
  10092. +  printf("Version %s\n",VERSION);
  10093. +  printf("\t-D                    become a daemon\n");
  10094. +  printf("\t-p port               listen on the specified port\n");
  10095. +  printf("\t-d debuglevel         set the debuglevel\n");
  10096. +  printf("\t-l log basename.      Basename for log/debug files\n");
  10097. +  printf("\t-n netbiosname.       the netbios name to advertise for this host\n");
  10098. +  printf("\t-B broadcast address  the address to use for broadcasts\n");
  10099. +  printf("\t-N netmask           the netmask to use for subnet determination\n");
  10100. +  printf("\t-H hosts file        load a netbios hosts file\n");
  10101. +  printf("\t-G group name        add a group name to be part of\n");
  10102. +  printf("\t-I ip-address        override the IP address\n");
  10103. +  printf("\t-C comment           sets the machine comment that appears in browse lists\n");
  10104. +  printf("\n");
  10105. +}
  10106. +
  10107. +
  10108. +/****************************************************************************
  10109. +  main program
  10110. +  **************************************************************************/
  10111. + int main(int argc,char *argv[])
  10112. +{
  10113. +  int port = NMB_PORT;
  10114. +  int opt;
  10115. +  extern FILE *dbf;
  10116. +  extern char *optarg;
  10117. +
  10118. +  *host_file = 0;
  10119. +
  10120. +  StartupTime = time(NULL);
  10121. +
  10122. +  TimeInit();
  10123. +
  10124. +  strcpy(debugf,NMBLOGFILE);
  10125. +
  10126. +  setup_logging(argv[0],False);
  10127. +
  10128. +  charset_initialise();
  10129. +
  10130. +  ipzero = *interpret_addr2("0.0.0.0");
  10131. +
  10132. +#ifdef LMHOSTSFILE
  10133. +  strcpy(host_file,LMHOSTSFILE);
  10134. +#endif
  10135. +
  10136. +  /* this is for people who can't start the program correctly */
  10137. +  while (argc > 1 && (*argv[1] != '-')) {
  10138. +    argv++;
  10139. +    argc--;
  10140. +  }
  10141. +
  10142. +  fault_setup(fault_continue);
  10143. +
  10144. +  signal(SIGHUP,SIGNAL_CAST sig_hup);
  10145. +
  10146. +  bcast_ip = ipzero;
  10147. +  myip = ipzero;
  10148. +
  10149. +  while ((opt = getopt (argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
  10150. +    {
  10151. +      switch (opt)
  10152. +    {
  10153. +    case 's':
  10154. +      strcpy(servicesf,optarg);
  10155. +      break;
  10156. +    case 'C':
  10157. +      strcpy(ServerComment,optarg);
  10158. +      break;
  10159. +    case 'G':
  10160. +      if (got_bcast && got_nmask) {
  10161. +        add_domain_entry(bcast_ip,Netmask,optarg, True);
  10162. +      } else {
  10163. +        DEBUG(0, ("Warning: option -G %s added before broadcast and netmask.\n",
  10164. +              optarg));
  10165. +        DEBUG(0, ("Assuming default values: bcast %s netmask %s\n",
  10166. +              inet_ntoa(bcast_ip), inet_ntoa(Netmask))); /* (i hope) */
  10167. +      }
  10168. +      break;
  10169. +    case 'H':
  10170. +      strcpy(host_file,optarg);
  10171. +      break;
  10172. +    case 'I':
  10173. +      myip = *interpret_addr2(optarg);
  10174. +      got_myip = True;
  10175. +      break;
  10176. +    case 'B':
  10177. +      bcast_ip = *interpret_addr2(optarg);
  10178. +      got_bcast = True;
  10179. +      break;
  10180. +    case 'N':
  10181. +      Netmask = *interpret_addr2(optarg);
  10182. +      got_nmask = True;
  10183. +      break;
  10184. +    case 'n':
  10185. +      strcpy(myname,optarg);
  10186. +      break;
  10187. +    case 'l':
  10188. +      sprintf(debugf,"%s.nmb",optarg);
  10189. +      break;
  10190. +    case 'i':
  10191. +      strcpy(scope,optarg);
  10192. +      strupper(scope);
  10193. +      break;
  10194. +    case 'D':
  10195. +      is_daemon = True;
  10196. +      break;
  10197. +    case 'd':
  10198. +      DEBUGLEVEL = atoi(optarg);
  10199. +      break;
  10200. +    case 'p':
  10201. +      port = atoi(optarg);
  10202. +      break;
  10203. +    case 'h':
  10204. +      usage(argv[0]);
  10205. +      exit(0);
  10206. +      break;
  10207. +    default:
  10208. +      if (!is_a_socket(0)) {
  10209. +        usage(argv[0]);
  10210. +      }
  10211. +      break;
  10212. +    }
  10213. +    }
  10214. +
  10215. +  DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
  10216. +  DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
  10217. +
  10218. +  init_structs();
  10219. +
  10220. +  if (!reload_services(False))
  10221. +    return(-1);    
  10222. +
  10223. +  if (!is_daemon && !is_a_socket(0)) {
  10224. +    DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  10225. +    is_daemon = True;
  10226. +  }
  10227. +  
  10228. +  if (is_daemon) {
  10229. +    DEBUG(2,("%s becoming a daemon\n",timestring()));
  10230. +    become_daemon();
  10231. +  }
  10232. +
  10233. +  DEBUG(3,("Opening sockets %d\n", port));
  10234. +
  10235. +  if (!open_sockets(is_daemon,port)) return 1;
  10236. +
  10237. +  if (*host_file) {
  10238. +    load_hosts_file(host_file);
  10239. +    DEBUG(3,("Loaded hosts file\n"));
  10240. +  }
  10241. +
  10242. +  if (!*ServerComment)
  10243. +    strcpy(ServerComment,"Samba %v");
  10244. +  string_sub(ServerComment,"%v",VERSION);
  10245. +  string_sub(ServerComment,"%h",myhostname);
  10246. +
  10247. +  add_my_names();
  10248. +  add_my_domains();
  10249. +
  10250. +  DEBUG(3,("Checked names\n"));
  10251. +  
  10252. +  write_browse_list();
  10253. +
  10254. +  DEBUG(3,("Dumped names\n"));
  10255. +
  10256. +  process();
  10257. +  close_sockets();
  10258. +
  10259. +  if (dbf)
  10260. +    fclose(dbf);
  10261. +  return(0);
  10262. +}
  10263. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nmblib.c samba-1.9.16alpha5/source/nmblib.c
  10264. --- samba-1.9.16alpha4/source/nmblib.c    Sat Jun  1 01:15:12 1996
  10265. +++ samba-1.9.16alpha5/source/nmblib.c    Wed Jun  5 01:16:27 1996
  10266. @@ -21,15 +21,104 @@
  10267.  */
  10268.  
  10269.  #include "includes.h"
  10270. -#include "nameserv.h"
  10271. +#include "localnet.h"
  10272. +#include "loadparm.h"
  10273.  
  10274. +extern struct in_addr myip;
  10275.  extern int DEBUGLEVEL;
  10276.  
  10277. -int num_good_sends=0;
  10278. -int  num_good_receives=0;
  10279. -static uint16 name_trn_id = 0;
  10280. -BOOL CanRecurse = True;
  10281. +int num_good_sends = 0;
  10282. +int num_good_receives = 0;
  10283.  extern pstring scope;
  10284. +extern pstring myname;
  10285. +extern struct in_addr ipzero;
  10286. +
  10287. +
  10288. +/****************************************************************************
  10289. +  print out a res_rec structure
  10290. +  ****************************************************************************/
  10291. +static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
  10292. +{
  10293. +  int i, j;
  10294. +
  10295. +  DEBUG(4,("    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
  10296. +       hdr,
  10297. +       namestr(&res->rr_name),
  10298. +       res->rr_type,
  10299. +       res->rr_class,
  10300. +       res->ttl));
  10301. +        
  10302. +  if (res->rdlength == 0 || res->rdata == NULL) return;
  10303. +
  10304. +  for (i = 0; i < res->rdlength; i+= 16)
  10305. +    {
  10306. +      DEBUG(4, ("    %s %3x char ", hdr, i));
  10307. +
  10308. +      for (j = 0; j < 16; j++)
  10309. +    {
  10310. +      unsigned char x = res->rdata[i+j];
  10311. +      if (x < 32 || x > 127) x = '.';
  10312. +      
  10313. +      if (i+j >= res->rdlength) break;
  10314. +      DEBUG(4, ("%c", x));
  10315. +    }
  10316. +      
  10317. +      DEBUG(4, ("   hex ", i));
  10318. +
  10319. +      for (j = 0; j < 16; j++)
  10320. +    {
  10321. +      if (i+j >= res->rdlength) break;
  10322. +      DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
  10323. +    }
  10324. +      
  10325. +      DEBUG(4, ("\n"));
  10326. +    }
  10327. +}
  10328. +
  10329. +/****************************************************************************
  10330. +  process a nmb packet
  10331. +  ****************************************************************************/
  10332. +void debug_nmb_packet(struct packet_struct *p)
  10333. +{
  10334. +  struct nmb_packet *nmb = &p->packet.nmb;
  10335. +  
  10336. +  DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n",
  10337. +       inet_ntoa(p->ip),
  10338. +       nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response)));
  10339. +  DEBUG(4,("    header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
  10340. +       BOOLSTR(nmb->header.nm_flags.bcast),
  10341. +       BOOLSTR(nmb->header.nm_flags.recursion_available),
  10342. +       BOOLSTR(nmb->header.nm_flags.recursion_desired),
  10343. +       BOOLSTR(nmb->header.nm_flags.trunc),
  10344. +       BOOLSTR(nmb->header.nm_flags.authoritative)));
  10345. +  DEBUG(4,("    header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
  10346. +       nmb->header.rcode,
  10347. +       nmb->header.qdcount,
  10348. +       nmb->header.ancount,
  10349. +       nmb->header.nscount,
  10350. +       nmb->header.arcount));
  10351. +
  10352. +  if (nmb->header.qdcount)
  10353. +    {
  10354. +      DEBUG(4,("    question: q_name=%s q_type=%d q_class=%d\n",
  10355. +           namestr(&nmb->question.question_name),
  10356. +           nmb->question.question_type,
  10357. +           nmb->question.question_class));
  10358. +    }
  10359. +
  10360. +  if (nmb->answers && nmb->header.ancount) 
  10361. +    {
  10362. +      debug_nmb_res_rec(nmb->answers,"answers");
  10363. +    }
  10364. +  if (nmb->nsrecs && nmb->header.nscount)
  10365. +    {
  10366. +      debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
  10367. +    }
  10368. +  if (nmb->additional && nmb->header.arcount)
  10369. +    {
  10370. +      debug_nmb_res_rec(nmb->additional,"additional");
  10371. +    }
  10372. +}
  10373.  
  10374.  /*******************************************************************
  10375.    handle "compressed" name pointers
  10376. @@ -38,7 +127,7 @@
  10377.                   BOOL *got_pointer,int *ret)
  10378.  {
  10379.    int loop_count=0;
  10380. -
  10381. +  
  10382.    while ((ubuf[*offset] & 0xC0) == 0xC0) {
  10383.      if (!*got_pointer) (*ret) += 2;
  10384.      (*got_pointer)=True;
  10385. @@ -54,8 +143,7 @@
  10386.    parse a nmb name from "compressed" format to something readable
  10387.    return the space taken by the name, or 0 if the name is invalid
  10388.    ******************************************************************/
  10389. -static int parse_nmb_name(char *inbuf,int offset,int length,
  10390. -              struct nmb_name *name)
  10391. +static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
  10392.  {
  10393.    int m,n=0;
  10394.    unsigned char *ubuf = (unsigned char *)inbuf;
  10395. @@ -186,11 +274,10 @@
  10396.  }
  10397.  
  10398.  /*******************************************************************
  10399. -  allocate are parse some resource records
  10400. +  allocate and parse some resource records
  10401.    ******************************************************************/
  10402.  static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
  10403. -                struct res_rec **recs,
  10404. -                int count)
  10405. +                struct res_rec **recs, int count)
  10406.  {
  10407.    int i;
  10408.    *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
  10409. @@ -382,7 +469,7 @@
  10410.    char buf[MAX_DGRAM_SIZE];
  10411.    int length;
  10412.    BOOL ok=False;
  10413. -
  10414. +  
  10415.    length = read_udp_socket(fd,buf,sizeof(buf));
  10416.    if (length < MIN_DGRAM_SIZE) return(NULL);
  10417.  
  10418. @@ -528,6 +615,7 @@
  10419.    if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
  10420.    if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
  10421.    ubuf[offset+3] |= (nmb->header.rcode & 0xF);
  10422. +
  10423.    RSSVAL(ubuf,offset+4,nmb->header.qdcount);
  10424.    RSSVAL(ubuf,offset+6,nmb->header.ancount);
  10425.    RSSVAL(ubuf,offset+8,nmb->header.nscount);
  10426. @@ -604,337 +692,6 @@
  10427.      return(read_packet(fd,type));
  10428.  
  10429.    return(NULL);
  10430. -}
  10431. -
  10432. -
  10433. -/****************************************************************************
  10434. -interpret a node status response
  10435. -****************************************************************************/
  10436. -static void interpret_node_status(char *p, char *master,char *rname)
  10437. -{
  10438. -  int level = (master||rname)?4:0;
  10439. -  int numnames = CVAL(p,0);
  10440. -  DEBUG(level,("received %d names\n",numnames));
  10441. -
  10442. -  if (rname) *rname = 0;
  10443. -  if (master) *master = 0;
  10444. -
  10445. -  p += 1;
  10446. -  while (numnames--)
  10447. -    {
  10448. -      char qname[17];
  10449. -      int type;
  10450. -      fstring flags;
  10451. -      int i;
  10452. -      *flags = 0;
  10453. -      StrnCpy(qname,p,15);
  10454. -      type = CVAL(p,15);
  10455. -      p += 16;
  10456. -
  10457. -      strcat(flags, (p[0] & 0x80) ? "<GROUP> " : "        ");
  10458. -      if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
  10459. -      if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
  10460. -      if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
  10461. -      if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
  10462. -      if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
  10463. -      if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
  10464. -      if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
  10465. -      if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
  10466. -
  10467. -      if (master && !*master && type == 0x1d) {
  10468. -    StrnCpy(master,qname,15);
  10469. -    trim_string(master,NULL," ");
  10470. -      }
  10471. -
  10472. -      if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
  10473. -    StrnCpy(rname,qname,15);
  10474. -    trim_string(rname,NULL," ");
  10475. -      }
  10476. -      
  10477. -      for (i = strlen( qname) ; --i >= 0 ; ) {
  10478. -    if (!isprint(qname[i])) qname[i] = '.';
  10479. -      }
  10480. -      DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags));
  10481. -      p+=2;
  10482. -    }
  10483. -  DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
  10484. -           IVAL(p,20),IVAL(p,24)));
  10485. -}
  10486. -
  10487. -
  10488. -/****************************************************************************
  10489. -  do a netbios name status query on a host
  10490. -
  10491. -  the "master" parameter is a hack used for finding workgroups.
  10492. -  **************************************************************************/
  10493. -BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  10494. -         struct in_addr to_ip,char *master,char *rname,
  10495. -         void (*fn)())
  10496. -{
  10497. -  BOOL found=False;
  10498. -  int retries = 2;
  10499. -  int retry_time = 5000;
  10500. -  struct timeval tval;
  10501. -  struct packet_struct p;
  10502. -  struct packet_struct *p2;
  10503. -  struct nmb_packet *nmb = &p.packet.nmb;
  10504. -
  10505. -  bzero((char *)&p,sizeof(p));
  10506. -
  10507. -  if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
  10508. -    (getpid()%(unsigned)100);
  10509. -  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  10510. -
  10511. -  nmb->header.name_trn_id = name_trn_id;
  10512. -  nmb->header.opcode = 0;
  10513. -  nmb->header.response = False;
  10514. -  nmb->header.nm_flags.bcast = False;
  10515. -  nmb->header.nm_flags.recursion_available = CanRecurse;
  10516. -  nmb->header.nm_flags.recursion_desired = recurse;
  10517. -  nmb->header.nm_flags.trunc = False;
  10518. -  nmb->header.nm_flags.authoritative = False;
  10519. -  nmb->header.rcode = 0;
  10520. -  nmb->header.qdcount = 1;
  10521. -  nmb->header.ancount = 0;
  10522. -  nmb->header.nscount = 0;
  10523. -  nmb->header.arcount = 0;
  10524. -
  10525. -  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  10526. -
  10527. -  nmb->question.question_type = 0x21;
  10528. -  nmb->question.question_class = 0x1;
  10529. -
  10530. -  p.ip = to_ip;
  10531. -  p.port = NMB_PORT;
  10532. -  p.fd = fd;
  10533. -  p.timestamp = time(NULL);
  10534. -  p.packet_type = NMB_PACKET;
  10535. -
  10536. -  GetTimeOfDay(&tval);
  10537. -
  10538. -  if (!send_packet(&p)) 
  10539. -    return(False);
  10540. -
  10541. -  retries--;
  10542. -
  10543. -  while (1)
  10544. -    {
  10545. -      struct timeval tval2;
  10546. -      GetTimeOfDay(&tval2);
  10547. -      if (TvalDiff(&tval,&tval2) > retry_time) {
  10548. -    if (!retries) break;
  10549. -    if (!found && !send_packet(&p))
  10550. -      return False;
  10551. -    GetTimeOfDay(&tval);
  10552. -    retries--;
  10553. -      }
  10554. -
  10555. -      if ((p2=receive_packet(fd,NMB_PACKET,90)))
  10556. -    {     
  10557. -      struct nmb_packet *nmb2 = &p2->packet.nmb;
  10558. -      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  10559. -          !nmb2->header.response) {
  10560. -        /* its not for us - maybe deal with it later */
  10561. -        if (fn) 
  10562. -          fn(p2);
  10563. -        else
  10564. -          free_packet(p2);
  10565. -        continue;
  10566. -      }
  10567. -      
  10568. -      if (nmb2->header.opcode != 0 ||
  10569. -          nmb2->header.nm_flags.bcast ||
  10570. -          nmb2->header.rcode ||
  10571. -          !nmb2->header.ancount ||
  10572. -          nmb2->answers->rr_type != 0x21) {
  10573. -        /* XXXX what do we do with this? could be a redirect, but
  10574. -           we'll discard it for the moment */
  10575. -        free_packet(p2);
  10576. -        continue;
  10577. -      }
  10578. -
  10579. -      interpret_node_status(&nmb2->answers->rdata[0], master,rname);
  10580. -      free_packet(p2);
  10581. -      return(True);
  10582. -    }
  10583. -    }
  10584. -  
  10585. -
  10586. -  DEBUG(0,("No status response (this is not unusual)\n"));
  10587. -
  10588. -  return(False);
  10589. -}
  10590. -
  10591. -
  10592. -/****************************************************************************
  10593. -  do a netbios name query to find someones IP
  10594. -  ****************************************************************************/
  10595. -BOOL name_query(int fd,char *name,int name_type, 
  10596. -        BOOL bcast,BOOL recurse,
  10597. -        struct in_addr to_ip, struct in_addr *ip,void (*fn)())
  10598. -{
  10599. -  BOOL found=False;
  10600. -  int retries = 3;
  10601. -  int retry_time = bcast?250:2000;
  10602. -  struct timeval tval;
  10603. -  struct packet_struct p;
  10604. -  struct packet_struct *p2;
  10605. -  struct nmb_packet *nmb = &p.packet.nmb;
  10606. -
  10607. -  bzero((char *)&p,sizeof(p));
  10608. -
  10609. -  if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + 
  10610. -    (getpid()%(unsigned)100);
  10611. -  name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
  10612. -
  10613. -  nmb->header.name_trn_id = name_trn_id;
  10614. -  nmb->header.opcode = 0;
  10615. -  nmb->header.response = False;
  10616. -  nmb->header.nm_flags.bcast = bcast;
  10617. -  nmb->header.nm_flags.recursion_available = CanRecurse;
  10618. -  nmb->header.nm_flags.recursion_desired = recurse;
  10619. -  nmb->header.nm_flags.trunc = False;
  10620. -  nmb->header.nm_flags.authoritative = False;
  10621. -  nmb->header.rcode = 0;
  10622. -  nmb->header.qdcount = 1;
  10623. -  nmb->header.ancount = 0;
  10624. -  nmb->header.nscount = 0;
  10625. -  nmb->header.arcount = 0;
  10626. -
  10627. -  make_nmb_name(&nmb->question.question_name,name,name_type,scope);
  10628. -
  10629. -  nmb->question.question_type = 0x20;
  10630. -  nmb->question.question_class = 0x1;
  10631. -
  10632. -  p.ip = to_ip;
  10633. -  p.port = NMB_PORT;
  10634. -  p.fd = fd;
  10635. -  p.timestamp = time(NULL);
  10636. -  p.packet_type = NMB_PACKET;
  10637. -
  10638. -  GetTimeOfDay(&tval);
  10639. -
  10640. -  if (!send_packet(&p)) 
  10641. -    return(False);
  10642. -
  10643. -  retries--;
  10644. -
  10645. -  while (1)
  10646. -    {
  10647. -      struct timeval tval2;
  10648. -      GetTimeOfDay(&tval2);
  10649. -      if (TvalDiff(&tval,&tval2) > retry_time) {
  10650. -    if (!retries) break;
  10651. -    if (!found && !send_packet(&p))
  10652. -      return False;
  10653. -    GetTimeOfDay(&tval);
  10654. -    retries--;
  10655. -      }
  10656. -
  10657. -      if ((p2=receive_packet(fd,NMB_PACKET,90)))
  10658. -    {     
  10659. -      struct nmb_packet *nmb2 = &p2->packet.nmb;
  10660. -      if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
  10661. -          !nmb2->header.response) {
  10662. -        /* its not for us - maybe deal with it later 
  10663. -           (put it on the queue?) */
  10664. -        if (fn) 
  10665. -          fn(p2);
  10666. -        else
  10667. -          free_packet(p2);
  10668. -        continue;
  10669. -      }
  10670. -      
  10671. -      if (nmb2->header.opcode != 0 ||
  10672. -          nmb2->header.nm_flags.bcast ||
  10673. -          nmb2->header.rcode ||
  10674. -          !nmb2->header.ancount) {
  10675. -        /* XXXX what do we do with this? could be a redirect, but
  10676. -           we'll discard it for the moment */
  10677. -        free_packet(p2);
  10678. -        continue;
  10679. -      }
  10680. -
  10681. -      if (ip) {
  10682. -        putip((char *)ip,&nmb2->answers->rdata[2]);
  10683. -        DEBUG(fn?3:2,("Got a positive name query response from %s",
  10684. -              inet_ntoa(p2->ip)));
  10685. -        DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
  10686. -      }
  10687. -      found=True; retries=0;
  10688. -      free_packet(p2);
  10689. -      if (fn) break;
  10690. -    }
  10691. -    }
  10692. -
  10693. -  return(found);
  10694. -}
  10695. -
  10696. -
  10697. -/****************************************************************************
  10698. -  construct and send a netbios DGRAM
  10699. -
  10700. -  Note that this currently sends all answers to port 138. thats the
  10701. -  wrong things to do! I should send to the requestors port. XXX
  10702. -  **************************************************************************/
  10703. -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,
  10704. -             char *srcname,char *dstname,
  10705. -             int src_type,int dest_type,
  10706. -             struct in_addr dest_ip,
  10707. -             struct in_addr src_ip)
  10708. -{
  10709. -  struct packet_struct p;
  10710. -  struct dgram_packet *dgram = &p.packet.dgram;
  10711. -  char *ptr,*p2;
  10712. -  char tmp[4];
  10713. -
  10714. -  bzero((char *)&p,sizeof(p));
  10715. -
  10716. -  dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
  10717. -  dgram->header.flags.node_type = M_NODE;
  10718. -  dgram->header.flags.first = True;
  10719. -  dgram->header.flags.more = False;
  10720. -  dgram->header.dgm_id = name_trn_id++;
  10721. -  dgram->header.source_ip = src_ip;
  10722. -  dgram->header.source_port = DGRAM_PORT;
  10723. -  dgram->header.dgm_length = 0; /* let build_dgram() handle this */
  10724. -  dgram->header.packet_offset = 0;
  10725. -  
  10726. -  make_nmb_name(&dgram->source_name,srcname,src_type,scope);
  10727. -  make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
  10728. -
  10729. -  ptr = &dgram->data[0];
  10730. -
  10731. -  /* now setup the smb part */
  10732. -  ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
  10733. -  memcpy(tmp,ptr,4);
  10734. -  set_message(ptr,17,17 + len,True);
  10735. -  memcpy(ptr,tmp,4);
  10736. -
  10737. -  CVAL(ptr,smb_com) = SMBtrans;
  10738. -  SSVAL(ptr,smb_vwv1,len);
  10739. -  SSVAL(ptr,smb_vwv11,len);
  10740. -  SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
  10741. -  SSVAL(ptr,smb_vwv13,3);
  10742. -  SSVAL(ptr,smb_vwv14,1);
  10743. -  SSVAL(ptr,smb_vwv15,1);
  10744. -  SSVAL(ptr,smb_vwv16,2);
  10745. -  p2 = smb_buf(ptr);
  10746. -  strcpy(p2,mailslot);
  10747. -  p2 = skip_string(p2,1);
  10748. -
  10749. -  memcpy(p2,buf,len);
  10750. -  p2 += len;
  10751. -
  10752. -  dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
  10753. -
  10754. -  p.ip = dest_ip;
  10755. -  p.port = DGRAM_PORT;
  10756. -  p.fd = fd;
  10757. -  p.timestamp = time(NULL);
  10758. -  p.packet_type = DGRAM_PACKET;
  10759. -
  10760. -  return(send_packet(&p));
  10761.  }
  10762.  
  10763.  
  10764. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nmblookup.c samba-1.9.16alpha5/source/nmblookup.c
  10765. --- samba-1.9.16alpha4/source/nmblookup.c    Sat May  4 17:50:24 1996
  10766. +++ samba-1.9.16alpha5/source/nmblookup.c    Wed Jun  5 01:16:27 1996
  10767. @@ -25,7 +25,6 @@
  10768.  #endif
  10769.  
  10770.  #include "includes.h"
  10771. -#include "nameserv.h"
  10772.  
  10773.  extern int DEBUGLEVEL;
  10774.  
  10775. @@ -35,6 +34,7 @@
  10776.  extern pstring myhostname;
  10777.  
  10778.  static BOOL got_bcast = False;
  10779. +struct in_addr ipzero;
  10780.  
  10781.  int ServerFD= -1;
  10782.  
  10783. @@ -123,6 +123,8 @@
  10784.    *lookup = 0;
  10785.  
  10786.    TimeInit();
  10787. +
  10788. +  ipzero = *interpret_addr2("0.0.0.0");
  10789.  
  10790.    setup_logging(argv[0],True);
  10791.  
  10792. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/nmbsync.c samba-1.9.16alpha5/source/nmbsync.c
  10793. --- samba-1.9.16alpha4/source/nmbsync.c    Sat May  4 17:50:24 1996
  10794. +++ samba-1.9.16alpha5/source/nmbsync.c    Wed Jun  5 01:16:27 1996
  10795. @@ -22,282 +22,162 @@
  10796.  
  10797.  #include "includes.h"
  10798.  #include "loadparm.h"
  10799. -#include "nameserv.h"
  10800. +#include "localnet.h"
  10801.  
  10802. -extern int DEBUGLEVEL;
  10803.  
  10804. -struct server_record *add_server_entry(char *name,int servertype,
  10805. -                       int ttl,char *comment,BOOL replace);
  10806. +extern int DEBUGLEVEL;
  10807.  
  10808. +extern pstring myname;
  10809. +extern struct in_addr bcast_ip;
  10810. +extern struct in_addr Netmask;
  10811. +
  10812. +extern int name_type;
  10813. +extern int max_protocol;
  10814. +extern struct in_addr dest_ip;
  10815. +extern int pid;
  10816. +extern int gid;
  10817. +extern int uid;
  10818. +extern int mid;
  10819. +extern BOOL got_pass;
  10820. +extern BOOL have_ip;
  10821. +extern pstring workgroup;
  10822. +extern pstring service;
  10823. +extern pstring desthost;
  10824. +extern BOOL connect_as_ipc;
  10825.  
  10826.  /****************************************************************************
  10827. -call a remote api
  10828. +fudge for getpass function
  10829.  ****************************************************************************/
  10830. -static BOOL call_remote_api(int fd,int cnum,int uid,int timeout,
  10831. -                char *inbuf,char *outbuf,
  10832. -                int prcnt,int drcnt,
  10833. -                int mprcnt,int mdrcnt,
  10834. -                int *rprcnt,int *rdrcnt,
  10835. -                char *param,char *data,
  10836. -                char **rparam,char **rdata)
  10837. +char *getsmbpass(char *pass)
  10838.  {
  10839. -  char *p1,*p2;
  10840. -
  10841. -  /* send a SMBtrans command */
  10842. -  bzero(outbuf,smb_size);
  10843. -  set_message(outbuf,14,0,True);
  10844. -  CVAL(outbuf,smb_com) = SMBtrans;
  10845. -  SSVAL(outbuf,smb_tid,cnum);
  10846. -  SSVAL(outbuf,smb_uid,uid);
  10847. -
  10848. -  p1 = smb_buf(outbuf);
  10849. -  strcpy(p1,"\\PIPE\\LANMAN");
  10850. -  p1 = skip_string(p1,1);
  10851. -  p2 = p1 + prcnt;
  10852. -
  10853. -  if (prcnt > 0)
  10854. -    memcpy(p1,param,prcnt);
  10855. -  if (drcnt > 0)
  10856. -    memcpy(p2,data,drcnt);
  10857. -
  10858. -  SSVAL(outbuf,smb_vwv0,prcnt); /* param count */
  10859. -  SSVAL(outbuf,smb_vwv1,drcnt); /* data count */
  10860. -  SSVAL(outbuf,smb_vwv2,mprcnt); /* mprcnt */
  10861. -  SSVAL(outbuf,smb_vwv3,mdrcnt); /* mdrcnt */
  10862. -  SSVAL(outbuf,smb_vwv4,0); /* msrcnt */
  10863. -  SSVAL(outbuf,smb_vwv5,0); /* flags */
  10864. -  SSVAL(outbuf,smb_vwv9,prcnt); /* pscnt */
  10865. -  SSVAL(outbuf,smb_vwv10,smb_offset(p1,outbuf)); /* psoff */
  10866. -  SSVAL(outbuf,smb_vwv11,drcnt); /* dscnt */
  10867. -  SSVAL(outbuf,smb_vwv12,smb_offset(p2,outbuf)); /* dsoff */
  10868. -  CVAL(outbuf,smb_vwv13) = 0; /* suwcnt */
  10869. -
  10870. -  set_message(outbuf,14,PTR_DIFF(p2+drcnt,smb_buf(outbuf)),False);
  10871. +    return "dummy"; /* return anything: it should be ignored anyway */
  10872. +}
  10873.  
  10874. -  send_smb(fd,outbuf);
  10875. +/****************************************************************************
  10876. +adds information retrieved from a NetServerEnum call
  10877. +****************************************************************************/
  10878. +static BOOL add_info(struct domain_record *d, struct work_record *work, int servertype)
  10879. +{
  10880. +  char *rparam = NULL;
  10881. +  char *rdata = NULL;
  10882. +  int rdrcnt,rprcnt;
  10883. +  char *p;
  10884. +  pstring param;
  10885. +  int uLevel = 1;
  10886. +  int count = -1;
  10887.    
  10888. -  if (receive_smb(fd,inbuf,timeout) &&
  10889. -      CVAL(inbuf,smb_rcls) == 0)
  10890. +  /* now send a SMBtrans command with api ServerEnum? */
  10891. +  p = param;
  10892. +  SSVAL(p,0,0x68); /* api number */
  10893. +  p += 2;
  10894. +  strcpy(p,"WrLehDz");
  10895. +  p = skip_string(p,1);
  10896. +  
  10897. +  strcpy(p,"B16BBDz");
  10898. +  
  10899. +  p = skip_string(p,1);
  10900. +  SSVAL(p,0,uLevel);
  10901. +  SSVAL(p,2,0x2000); /* buf length */
  10902. +  p += 4;
  10903. +  SIVAL(p,0,servertype);
  10904. +  p += 4;
  10905. +  
  10906. +  strcpy(p, work->work_group);
  10907. +  p = skip_string(p,1);
  10908. +  
  10909. +  if (cli_call_api(PTR_DIFF(p,param),0, 8,10000,
  10910. +           &rprcnt,&rdrcnt, param,NULL,
  10911. +           &rparam,&rdata))
  10912.      {
  10913. -      if (rparam)
  10914. -    *rparam = inbuf+4 + SVAL(inbuf,smb_vwv4);
  10915. -      if (rdata)
  10916. -    *rdata = inbuf+4 + SVAL(inbuf,smb_vwv7);
  10917. -      if (rprcnt)
  10918. -    *rprcnt = SVAL(inbuf,smb_vwv3);
  10919. -      if (rdrcnt)
  10920. -    *rdrcnt = SVAL(inbuf,smb_vwv6);
  10921. -      return(True);
  10922. +      int res = SVAL(rparam,0);
  10923. +      int converter=SVAL(rparam,2);
  10924. +      int i;
  10925. +      
  10926. +      if (res == 0)
  10927. +    {
  10928. +      count=SVAL(rparam,4);
  10929. +      p = rdata;
  10930. +      
  10931. +      for (i = 0;i < count;i++, p += 26)
  10932. +        {
  10933. +          char *sname = p;
  10934. +          uint32 stype = IVAL(p,18);
  10935. +          int comment_offset = IVAL(p,22) & 0xFFFF;
  10936. +          char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
  10937. +          
  10938. +          struct work_record *w = work;
  10939. +          
  10940. +          DEBUG(4, ("\t%-16.16s     %08x    %s\n", sname, stype, cmnt));
  10941. +          
  10942. +          if (stype & SV_TYPE_DOMAIN_ENUM)
  10943. +        {
  10944. +          /* creates workgroup on remote subnet */
  10945. +          if ((w = find_workgroupstruct(d,sname, False)))
  10946. +            {
  10947. +              if (ip_equal(bcast_ip, d->bcast_ip))
  10948. +            {
  10949. +              announce_request(w, d->bcast_ip);
  10950. +            }
  10951. +            }
  10952. +        }
  10953. +          
  10954. +          add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
  10955. +        }
  10956. +    }
  10957.      }
  10958. -
  10959. -  return(False);
  10960. +  
  10961. +  if (rparam) free(rparam);
  10962. +  if (rdata) free(rdata);
  10963. +  
  10964. +  return(True);
  10965.  }
  10966.  
  10967.  
  10968.  /*******************************************************************
  10969. -  synchronise browse lists with another browse server
  10970. +  synchronise browse lists with another browse server.
  10971. +
  10972. +  log in on the remote server's SMB port to their IPC$ service,
  10973. +  do a NetServerEnum and update our server and workgroup databases.
  10974.    ******************************************************************/
  10975. -void sync_browse_lists(char *name,int name_type,char *myname,
  10976. -               char *domain,struct in_addr ip)
  10977. +void sync_browse_lists(struct work_record *work, char *name, int nm_type,
  10978. +               struct in_addr ip)
  10979.  {
  10980. -  char *protocol = "LM1.2X002";
  10981. -  char *service = "IPC$";
  10982. -  char *dev = "IPC";
  10983. -  int timeout=2000;
  10984. -  char *inbuf=NULL;
  10985. -  pstring outbuf;
  10986. -  char *p;
  10987. -  int len;
  10988. -  uint32 sesskey;
  10989. -  int cnum,uid;
  10990. -  BOOL ret;
  10991. -
  10992. -  int fd = open_socket_out(SOCK_STREAM, &ip, SMB_PORT);
  10993. -  if (fd < 0) {
  10994. -    DEBUG(3,("Failed to connect to %s at %s\n",name,inet_ntoa(ip)));
  10995. -    return;
  10996. -  }
  10997. -
  10998. -  if (!(inbuf = (char *)malloc(0xFFFF+1024))) return;  
  10999. -
  11000. -  /* put in the destination name */
  11001. -  len = 4;
  11002. -  p = outbuf+len;
  11003. -  name_mangle(name,p,name_type);
  11004. -  len += name_len(p);
  11005. -
  11006. -  /* and my name */
  11007. -  p = outbuf+len;
  11008. -  name_mangle(myname,p,0x20);
  11009. -  len += name_len(p);
  11010. +    struct domain_record *d;
  11011. +    pid = getpid();
  11012. +    uid = getuid();
  11013. +    gid = getgid();
  11014. +    mid = pid + 100;
  11015. +    name_type = nm_type;
  11016.  
  11017. -  _smb_setlen(outbuf,len);
  11018. -  CVAL(outbuf,0) = 0x81;
  11019. +    got_pass = True;
  11020.  
  11021. -  send_smb(fd,outbuf);
  11022. -  receive_smb(fd,inbuf,5000);
  11023. -  
  11024. -  bzero(outbuf,smb_size);
  11025. +    DEBUG(4, ("sync browse lists with %s for %s %s\n",
  11026. +            work->work_group, name, inet_ntoa(ip)));
  11027.  
  11028. -  /* setup the protocol string */
  11029. -  set_message(outbuf,0,strlen(protocol)+2,True);
  11030. -  p = smb_buf(outbuf);
  11031. -  *p++ = 2;
  11032. -  strcpy(p,protocol);
  11033. -
  11034. -  CVAL(outbuf,smb_com) = SMBnegprot;
  11035. -  CVAL(outbuf,smb_flg) = 0x8;
  11036. -  SSVAL(outbuf,smb_flg2,0x1);
  11037. -
  11038. -  send_smb(fd,outbuf);
  11039. -  bzero(inbuf,smb_size);
  11040. -  ret = receive_smb(fd,inbuf,timeout);
  11041. -  
  11042. -  if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) {
  11043. -    DEBUG(3,("%s rejected the protocol\n",name));
  11044. -    close(fd);
  11045. -    if (inbuf) free(inbuf);
  11046. -    return;
  11047. -  }
  11048. -
  11049. -  sesskey = IVAL(inbuf,smb_vwv6);
  11050. -
  11051. -  bzero(outbuf,smb_size);
  11052. -  set_message(outbuf,10,2,True);
  11053. -  CVAL(outbuf,smb_com) = SMBsesssetupX;
  11054. -
  11055. -  CVAL(outbuf,smb_vwv0) = 0xFF;
  11056. -  SSVAL(outbuf,smb_vwv2,0xFFFF);
  11057. -  SSVAL(outbuf,smb_vwv3,2);
  11058. -  SSVAL(outbuf,smb_vwv4,1);
  11059. -  SIVAL(outbuf,smb_vwv5,sesskey);
  11060. -  SSVAL(outbuf,smb_vwv7,1);
  11061. -
  11062. -  send_smb(fd,outbuf);
  11063. -  bzero(inbuf,smb_size);
  11064. -  ret = receive_smb(fd,inbuf,timeout);
  11065. -  if (!ret || CVAL(inbuf,smb_rcls)) {
  11066. -    DEBUG(3,("%s rejected session setup\n",name));
  11067. -    close(fd);
  11068. -    if (inbuf) free(inbuf);
  11069. -    return;
  11070. -  }
  11071. -
  11072. -  uid = SVAL(inbuf,smb_uid);
  11073. -
  11074. -  bzero(outbuf,smb_size);
  11075. -  set_message(outbuf,4,2 + (2 + strlen(name) + 1 + strlen(service)) +
  11076. -       1 + strlen(dev),True);
  11077. -  CVAL(outbuf,smb_com) = SMBtconX;
  11078. -  SSVAL(outbuf,smb_uid,uid);
  11079. -
  11080. -  SSVAL(outbuf,smb_vwv0,0xFF);
  11081. -  SSVAL(outbuf,smb_vwv3,1);
  11082. -
  11083. -  p = smb_buf(outbuf) + 1;
  11084. -  strcpy(p, "\\\\");
  11085. -  strcat(p, name);
  11086. -  strcat(p, "\\");
  11087. -  strcat(p,service);
  11088. -  p = skip_string(p,1);
  11089. -  strcpy(p,dev);
  11090. +    strcpy(workgroup,work->work_group);
  11091. +    strcpy(desthost,name);
  11092. +    dest_ip = ip;
  11093.  
  11094. -  send_smb(fd,outbuf);
  11095. -  bzero(inbuf,smb_size);
  11096. -  ret = receive_smb(fd,inbuf,timeout);
  11097. -  if (!ret || CVAL(inbuf,smb_rcls)) {
  11098. -    DEBUG(3,("%s rejected IPC connect (%d,%d)\n",name,
  11099. -         CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err)));
  11100. -    close(fd);
  11101. -    if (inbuf) free(inbuf);
  11102. -    return;
  11103. -  }
  11104. +    if (zero_ip(dest_ip)) return;
  11105. +    have_ip = True;
  11106.  
  11107. -  cnum = SVAL(inbuf,smb_tid);
  11108. -  
  11109. -  /* now I need to send a NetServerEnum */
  11110. -  {
  11111. -    fstring param;
  11112. -    uint32 *typep;
  11113. -    char *rparam,*rdata;
  11114. -
  11115. -    p = param;
  11116. -    SSVAL(p,0,0x68); /* api number */
  11117. -    p += 2;
  11118. -    strcpy(p,"WrLehDz");
  11119. -    p = skip_string(p,1);
  11120. -
  11121. -    strcpy(p,"B16BBDz");
  11122. -
  11123. -    p = skip_string(p,1);
  11124. -    SSVAL(p,0,1); /* level 1 */
  11125. -    SSVAL(p,2,0xFFFF - 500); /* buf length */
  11126. -    p += 4;
  11127. -    typep = (uint32 *)p;
  11128. -    p += 4;
  11129. -    strcpy(p,domain);
  11130. -    strupper(p);
  11131. -    p = skip_string(p,1);
  11132. -
  11133. -    SIVAL(typep,0,0x80000000); /* domain list */
  11134. -
  11135. -    if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
  11136. -            PTR_DIFF(p,param),0,
  11137. -            8,0xFFFF - 500,
  11138. -            NULL,NULL,
  11139. -            param,NULL,
  11140. -            &rparam,&rdata) && SVAL(rparam,0)==0)
  11141. -    {
  11142. -      int converter=SVAL(rparam,2);
  11143. -      int count=SVAL(rparam,4);
  11144. -      int i;
  11145. -      char *p2 = rdata;
  11146. -      for (i=0;i<count;i++) {
  11147. -    char *sname = p2;
  11148. -    uint32 type = IVAL(p2,18);
  11149. -    int comment_offset = IVAL(p2,22) & 0xFFFF;
  11150. -    char *comment = comment_offset?(rdata+comment_offset-converter):"";
  11151. -
  11152. -    add_server_entry(sname,type,lp_max_ttl(),comment,False);
  11153. -    p2 += 26;
  11154. -      }
  11155. -    }
  11156. +    if (!(d = find_domain(ip))) return;
  11157.  
  11158. -    SIVAL(typep,0,0xFFFFFFFF); /* server list */
  11159. +    connect_as_ipc = True;
  11160.  
  11161. -    if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
  11162. -            PTR_DIFF(p,param),0,
  11163. -            8,0xFFFF - 500,
  11164. -            NULL,NULL,
  11165. -            param,NULL,
  11166. -            &rparam,&rdata) && SVAL(rparam,0)==0)
  11167. -    {
  11168. -      int converter=SVAL(rparam,2);
  11169. -      int count=SVAL(rparam,4);
  11170. -      int i;
  11171. +    /* connect as server and get domains, then servers */
  11172.  
  11173. -      p = rdata;
  11174. -      for (i=0;i<count;i++) {
  11175. -    char *sname = p;
  11176. -    uint32 type = IVAL(p,18);
  11177. -    int comment_offset = IVAL(p,22) & 0xFFFF;
  11178. -    char *comment = comment_offset?(rdata+comment_offset-converter):"";
  11179. -
  11180. -    add_server_entry(sname,type,lp_max_ttl(),comment,False);
  11181. -    p += 26;
  11182. -      }
  11183. -    }
  11184. -  }
  11185. +    sprintf(service,"\\\\%s\\IPC$", name);
  11186. +    strupper(service);
  11187.  
  11188. -  /* close up */
  11189. -  bzero(outbuf,smb_size);
  11190. -  set_message(outbuf,0,0,True);
  11191. -  CVAL(outbuf,smb_com) = SMBtdis;
  11192. -  SSVAL(outbuf,smb_uid,uid);
  11193. -  SSVAL(outbuf,smb_tid,cnum);
  11194. -  send_smb(fd,outbuf);
  11195. -  receive_smb(fd,inbuf,1000);
  11196. -  
  11197. -  close(fd);
  11198. -  if (inbuf) free(inbuf);
  11199. +    if (cli_open_sockets(SMB_PORT))
  11200. +    {
  11201. +        if (cli_send_login(NULL,NULL,True,True))
  11202. +        {
  11203. +            add_info(d, work, SV_TYPE_DOMAIN_ENUM);
  11204. +            add_info(d, work, SV_TYPE_ALL&~SV_TYPE_DOMAIN_ENUM);
  11205. +        }
  11206. +
  11207. +        close_sockets();
  11208. +    }
  11209.  }
  11210. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/params.c samba-1.9.16alpha5/source/params.c
  11211. --- samba-1.9.16alpha4/source/params.c    Sat May  4 17:50:24 1996
  11212. +++ samba-1.9.16alpha5/source/params.c    Wed Jun  5 01:16:27 1996
  11213. @@ -63,23 +63,74 @@
  11214.  static char *pszParmFile = NULL;
  11215.  extern int DEBUGLEVEL;
  11216.  
  11217. -/* local prototypes */
  11218. -static BOOL enumerate_parameters(FILE *infile, PM_PARMFUNC pfunc);
  11219. -static BOOL enumerate_sections(FILE *infile, 
  11220. -                   PM_SECFUNC sfunc, PM_PARMFUNC pfunc);
  11221. -
  11222. -/* prototypes for local toolbox functions */
  11223. -static void trimleft(char *psz);
  11224. -static void trimright(char *psz);
  11225. -static void collapse_spaces(char *psz);
  11226. -static int  firstnonwhite(char *psz);
  11227. +
  11228. +/**************************************************************************
  11229. +Strip all leading whitespace from a string.
  11230. +**************************************************************************/
  11231. +static void trimleft(char *psz)
  11232. +{
  11233. +   char *pszDest;
  11234. +
  11235. +   pszDest = psz;
  11236. +   if (psz != NULL)
  11237. +   {
  11238. +      while (*psz != '\0' && isspace(*psz))
  11239. +     psz++;
  11240. +      while (*psz != '\0')
  11241. +     *pszDest++ = *psz++;
  11242. +      *pszDest = '\0';
  11243. +   }
  11244. +}
  11245. +
  11246. +/**************************************************************************
  11247. +Strip all trailing whitespace from a string.
  11248. +**************************************************************************/
  11249. +static void trimright(char *psz)
  11250. +{
  11251. +   char *pszTemp;
  11252. +
  11253. +   if (psz != NULL && psz[0] != '\0')
  11254. +   {
  11255. +      pszTemp = psz + strlen(psz) - 1;
  11256. +      while (isspace(*pszTemp))
  11257. +     *pszTemp-- = '\0';
  11258. +   }
  11259. +}
  11260. +
  11261. +/***********************************************************************
  11262. +Collapse each whitespace area in a string to a single space.
  11263. +***********************************************************************/
  11264. +static void collapse_spaces(char *psz)
  11265. +{
  11266. +   while (*psz)
  11267. +      if (isspace(*psz))
  11268. +      {
  11269. +     *psz++ = ' ';
  11270. +     trimleft(psz);
  11271. +      }
  11272. +      else
  11273. +     psz++;
  11274. +}
  11275. +
  11276. +/**************************************************************************
  11277. +Return the value of the first non-white character in the specified string.
  11278. +The terminating NUL counts as non-white for the purposes of this function.
  11279. +Note - no check for a NULL string! What would we return?
  11280. +**************************************************************************/
  11281. +static int firstnonwhite(char *psz)
  11282. +{
  11283. +   while (isspace(*psz) && (*psz != '\0'))
  11284. +      psz++;
  11285. +   return (*psz);
  11286. +}
  11287. +
  11288.  
  11289.  /**************************************************************************
  11290.  Identifies all parameters in the current section, calls the parameter
  11291.  function for each. Ignores comment lines, stops and backs up in file when
  11292.  a section is encountered. Returns True on success, False on error.
  11293.  **************************************************************************/
  11294. -static BOOL enumerate_parameters(FILE *fileIn, PM_PARMFUNC pfunc)
  11295. +static BOOL enumerate_parameters(FILE *fileIn, BOOL (*pfunc)(char *,char *))
  11296.  {
  11297.     pstring szBuf;
  11298.     char *pszTemp;
  11299. @@ -186,8 +237,8 @@
  11300.  parameter names will have all internal whitespace areas collapsed to a 
  11301.  single space for processing.
  11302.  **************************************************************************/
  11303. -static BOOL enumerate_sections(FILE *fileIn, 
  11304. -                   PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
  11305. +static BOOL enumerate_sections(FILE *fileIn,
  11306. +                   BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *))
  11307.  {
  11308.     pstring szBuf;
  11309.     BOOL bRetval;
  11310. @@ -246,7 +297,7 @@
  11311.  
  11312.  Returns True if successful, else False.
  11313.  **************************************************************************/
  11314. -BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
  11315. +BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *))
  11316.  {
  11317.     FILE *fileIn;
  11318.     BOOL bRetval;
  11319. @@ -274,62 +325,3 @@
  11320.  }
  11321.  
  11322.  
  11323. -/**************************************************************************
  11324. -Strip all leading whitespace from a string.
  11325. -**************************************************************************/
  11326. -static void trimleft(char *psz)
  11327. -{
  11328. -   char *pszDest;
  11329. -
  11330. -   pszDest = psz;
  11331. -   if (psz != NULL)
  11332. -   {
  11333. -      while (*psz != '\0' && isspace(*psz))
  11334. -     psz++;
  11335. -      while (*psz != '\0')
  11336. -     *pszDest++ = *psz++;
  11337. -      *pszDest = '\0';
  11338. -   }
  11339. -}
  11340. -
  11341. -/**************************************************************************
  11342. -Strip all trailing whitespace from a string.
  11343. -**************************************************************************/
  11344. -static void trimright(char *psz)
  11345. -{
  11346. -   char *pszTemp;
  11347. -
  11348. -   if (psz != NULL && psz[0] != '\0')
  11349. -   {
  11350. -      pszTemp = psz + strlen(psz) - 1;
  11351. -      while (isspace(*pszTemp))
  11352. -     *pszTemp-- = '\0';
  11353. -   }
  11354. -}
  11355. -
  11356. -/***********************************************************************
  11357. -Collapse each whitespace area in a string to a single space.
  11358. -***********************************************************************/
  11359. -static void collapse_spaces(char *psz)
  11360. -{
  11361. -   while (*psz)
  11362. -      if (isspace(*psz))
  11363. -      {
  11364. -     *psz++ = ' ';
  11365. -     trimleft(psz);
  11366. -      }
  11367. -      else
  11368. -     psz++;
  11369. -}
  11370. -
  11371. -/**************************************************************************
  11372. -Return the value of the first non-white character in the specified string.
  11373. -The terminating NUL counts as non-white for the purposes of this function.
  11374. -Note - no check for a NULL string! What would we return?
  11375. -**************************************************************************/
  11376. -static int firstnonwhite(char *psz)
  11377. -{
  11378. -   while (isspace(*psz) && (*psz != '\0'))
  11379. -      psz++;
  11380. -   return (*psz);
  11381. -}
  11382. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/params.h samba-1.9.16alpha5/source/params.h
  11383. --- samba-1.9.16alpha4/source/params.h    Sat May  4 17:50:24 1996
  11384. +++ samba-1.9.16alpha5/source/params.h    Wed Jun  5 01:16:27 1996
  11385. @@ -32,14 +32,9 @@
  11386.  #include <stdio.h>
  11387.  #include "smb.h"
  11388.  
  11389. -typedef BOOL (* PM_PARMFUNC)(char *pszParmName, char *pszParmValue);
  11390. -typedef BOOL (* PM_SECFUNC)(char *pszSectionName);
  11391. -
  11392.  #define PM_NOFILE               1
  11393.  #define PM_NOFILENAME           2
  11394.  #define PM_FILEERROR            3
  11395. -
  11396. -extern BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc);
  11397.  
  11398.  #endif
  11399.  
  11400. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/password.c samba-1.9.16alpha5/source/password.c
  11401. --- samba-1.9.16alpha4/source/password.c    Sat Jun  1 01:15:12 1996
  11402. +++ samba-1.9.16alpha5/source/password.c    Wed Jun  5 01:16:28 1996
  11403. @@ -1258,7 +1258,7 @@
  11404.    fstring desthost;
  11405.    struct in_addr dest_ip;
  11406.    extern struct in_addr myip;
  11407. -  int port = 139;
  11408. +  int port = SMB_PORT;
  11409.    BOOL ret;
  11410.  
  11411.    if (password_client >= 0)
  11412. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/proto.h samba-1.9.16alpha5/source/proto.h
  11413. --- samba-1.9.16alpha4/source/proto.h    Thu Jan  1 10:00:00 1970
  11414. +++ samba-1.9.16alpha5/source/proto.h    Tue Jun  4 16:41:30 1996
  11415. @@ -0,0 +1,506 @@
  11416. +BOOL check_access(int snum);
  11417. +BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
  11418. +BOOL fromhost(int sock,struct from_host *f);
  11419. +char *unix2dos_format(char *str,BOOL overwrite);
  11420. +char *dos2unix_format(char *str, BOOL overwrite);
  11421. +int interpret_character_set(char *str, int def);
  11422. +void charset_initialise(void);
  11423. +void add_char_string(char *s);
  11424. +BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
  11425. +BOOL chgpasswd(char *name,char *oldpass,char *newpass);
  11426. +BOOL chgpasswd(char *name,char *oldpass,char *newpass);
  11427. +void setup_pkt(char *outbuf);
  11428. +void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
  11429. +void cmd_help(void);
  11430. +BOOL reopen_connection(char *inbuf,char *outbuf);
  11431. +char *smb_errstr(char *inbuf);
  11432. +void cli_setup_pkt(char *outbuf);
  11433. +BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
  11434. +                int *param_len, char **data,char **param);
  11435. +BOOL cli_send_session_request(char *inbuf, char *outbuf);
  11436. +BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup);
  11437. +void cli_send_logout(void);
  11438. +BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
  11439. +          int *rdrcnt, char *param,char *data, char **rparam,char **rdata);
  11440. +BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags,
  11441. +            char *data,char *param,uint16 *setup, int ldata,int lparam,
  11442. +            int lsetup,int mdata,int mparam,int msetup);
  11443. +BOOL cli_open_sockets(int port);
  11444. +BOOL cli_reopen_connection(char *inbuf,char *outbuf);
  11445. +char *smb_errstr(char *inbuf);
  11446. +int strslashcmp(const char *s1, const char *s2);
  11447. +void cmd_block(void);
  11448. +void cmd_tarmode(void);
  11449. +void cmd_setmode(void);
  11450. +void cmd_tar(char *inbuf, char *outbuf);
  11451. +int process_tar(char *inbuf, char *outbuf);
  11452. +int clipfind(char **aret, int ret, char *tok);
  11453. +int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
  11454. +void init_dptrs(void);
  11455. +char *dptr_path(int key);
  11456. +char *dptr_wcard(int key);
  11457. +BOOL dptr_set_wcard(int key, char *wcard);
  11458. +BOOL dptr_set_attr(int key, uint16 attr);
  11459. +uint16 dptr_attr(int key);
  11460. +void dptr_close(int key);
  11461. +void dptr_closecnum(int cnum);
  11462. +void dptr_idlecnum(int cnum);
  11463. +void dptr_closepath(char *path,int pid);
  11464. +int dptr_create(int cnum,char *path, BOOL expect_close,int pid);
  11465. +BOOL dptr_fill(char *buf1,unsigned int key);
  11466. +BOOL dptr_zero(char *buf);
  11467. +void *dptr_fetch(char *buf,int *num);
  11468. +void *dptr_fetch_lanman2(char *params,int dptr_num);
  11469. +BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
  11470. +void *OpenDir(char *name);
  11471. +void CloseDir(void *p);
  11472. +char *ReadDirName(void *p);
  11473. +BOOL SeekDir(void *p,int pos);
  11474. +int TellDir(void *p);
  11475. +void DirCacheAdd(char *path,char *name,char *dname,int snum);
  11476. +char *DirCacheCheck(char *path,char *name,int snum);
  11477. +void DirCacheFlush(int snum);
  11478. +void fault_setup(void (*fn)());
  11479. +char *getsmbpass(char *prompt)    ;
  11480. +int reply_trans(char *inbuf,char *outbuf);
  11481. +int interpret_coding_system(char *str, int def);
  11482. +char *lp_string(char *s);
  11483. +BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
  11484. +int lp_add_service(char *pszService, int iDefaultService);
  11485. +BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
  11486. +BOOL lp_file_list_changed(void);
  11487. +BOOL lp_snum_ok(int iService);
  11488. +BOOL lp_loaded(void);
  11489. +void lp_killunused(BOOL (*snumused)(int ));
  11490. +BOOL lp_load(char *pszFname,BOOL global_only);
  11491. +int lp_numservices(void);
  11492. +void lp_dump(void);
  11493. +int lp_servicenumber(char *pszServiceName);
  11494. +char *my_workgroup(void);
  11495. +char *volume_label(int snum);
  11496. +BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset);
  11497. +BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
  11498. +BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
  11499. +int get_share_mode_by_fnum(int cnum,int fnum,int *pid);
  11500. +int get_share_mode_byname(int cnum,char *fname,int *pid);
  11501. +int get_share_mode(int cnum,struct stat *sbuf,int *pid);
  11502. +void del_share_mode(int fnum);
  11503. +BOOL set_share_mode(int fnum,int mode);
  11504. +void clean_share_files(void);
  11505. +int str_checksum(char *s);
  11506. +BOOL is_8_3(char *fname);
  11507. +void create_mangled_stack(int size);
  11508. +BOOL check_mangled_stack(char *s);
  11509. +BOOL is_mangled(char *s);
  11510. +void mangle_name_83(char *s);
  11511. +BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
  11512. +int reply_sends(char *inbuf,char *outbuf);
  11513. +int reply_sendstrt(char *inbuf,char *outbuf);
  11514. +int reply_sendtxt(char *inbuf,char *outbuf);
  11515. +int reply_sendend(char *inbuf,char *outbuf);
  11516. +void announce_request(struct work_record *work, struct in_addr ip);
  11517. +void do_announce_request(char *info, char *to_name, int announce_type, int from,
  11518. +             int to, struct in_addr dest_ip);
  11519. +void announce_backup(void);
  11520. +void announce_host(void);
  11521. +void announce_master(void);
  11522. +struct work_record *remove_workgroup(struct domain_record *d, struct work_record *work);
  11523. +void expire_browse_cache(time_t t);
  11524. +struct work_record *find_workgroupstruct(struct domain_record *d, fstring name, BOOL add);
  11525. +struct domain_record *find_domain(struct in_addr source_ip);
  11526. +struct domain_record *add_domain_entry(struct in_addr source_ip, struct in_addr source_mask,
  11527. +                       char *name, BOOL add);
  11528. +struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
  11529. +                          time_t ttl, struct in_addr ip);
  11530. +struct server_record *add_server_entry(struct domain_record *d, struct work_record *work,
  11531. +                       char *name,int servertype, int ttl,char *comment,
  11532. +                       BOOL replace);
  11533. +void write_browse_list(void);
  11534. +void expire_servers(time_t t);
  11535. +void check_master_browser(void);
  11536. +void browser_gone(char *work_name, struct in_addr ip);
  11537. +void send_election(struct domain_record *d, char *group,uint32 criterion,
  11538. +           int timeup,char *name);
  11539. +void become_nonmaster(struct domain_record *d, struct work_record *work);
  11540. +void run_elections(void);
  11541. +void process_election(struct packet_struct *p,char *buf);
  11542. +BOOL check_elections(void);
  11543. +BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
  11544. +         struct in_addr to_ip,char *master,char *rname,
  11545. +         void (*fn)());
  11546. +BOOL name_query(int fd,char *name,int name_type, 
  11547. +        BOOL bcast,BOOL recurse,
  11548. +        struct in_addr to_ip, struct in_addr *ip,void (*fn)());
  11549. +void expire_netbios_response_entries(time_t t);
  11550. +void reply_netbios_packet(struct packet_struct *p1,int trn_id,int rcode,int opcode,
  11551. +              struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
  11552. +              char *data,int len);
  11553. +uint16 initiate_netbios_packet(int fd,int quest_type,char *name,int name_type,
  11554. +                   int nb_flags,BOOL bcast,BOOL recurse,struct in_addr to_ip);
  11555. +void send_name_reg(void);
  11556. +void queue_netbios_pkt_wins(int fd,int quest_type,enum cmd_type cmd,
  11557. +                char *name,int name_type,int nb_flags,
  11558. +                BOOL bcast,BOOL recurse,struct in_addr to_ip);
  11559. +void queue_netbios_packet(int fd,int quest_type,enum cmd_type cmd,char *name,
  11560. +              int name_type,int nb_flags,BOOL bcast,BOOL recurse,
  11561. +              struct in_addr to_ip);
  11562. +struct name_response_record *find_name_query(uint16 id);
  11563. +void queue_packet(struct packet_struct *packet);
  11564. +void run_packet_queue();
  11565. +void listen_for_packets(BOOL run_election);
  11566. +BOOL interpret_node_status(char *p, struct nmb_name *name,int t,
  11567. +               char *serv_name, struct in_addr ip);
  11568. +BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
  11569. +             char *dstname,int src_type,int dest_type,
  11570. +             struct in_addr dest_ip,struct in_addr src_ip);
  11571. +void remove_name(struct name_record *n);
  11572. +void dump_names(void);
  11573. +void remove_netbios_name(char *name,int type, enum name_source source,
  11574. +             struct in_addr ip);
  11575. +struct name_record *add_netbios_entry(char *name, int type, int nb_flags, int ttl,
  11576. +                      enum name_source source, struct in_addr ip);
  11577. +void remove_name_entry(char *name,int type);
  11578. +void add_name_entry(char *name,int type,int nb_flags);
  11579. +void add_my_names(void);
  11580. +void expire_names(time_t t);
  11581. +void response_name_release(struct packet_struct *p);
  11582. +void reply_name_release(struct packet_struct *p);
  11583. +void response_name_reg(struct packet_struct *p);
  11584. +void reply_name_reg(struct packet_struct *p);
  11585. +void reply_name_status(struct packet_struct *p);
  11586. +struct name_record *search_for_name(struct nmb_name *question,
  11587. +                    struct in_addr ip, int Time, int search);
  11588. +void process_nmb(struct packet_struct *p);
  11589. +void reset_server(char *name, int state, struct in_addr ip);
  11590. +void tell_become_backup(void);
  11591. +void do_browser_lists(void);
  11592. +void sync_server(enum cmd_type cmd, char *serv_name, char *work_name, int name_type,
  11593. +         struct in_addr ip);
  11594. +void update_from_reg(char *name, int type, struct in_addr ip);
  11595. +void add_my_domains(void);
  11596. +BOOL same_context(struct dgram_packet *dgram);
  11597. +BOOL listening_name(struct work_record *work, struct nmb_name *n);
  11598. +void process_logon_packet(struct packet_struct *p,char *buf,int len);
  11599. +BOOL listening_type(struct packet_struct *p, int command);
  11600. +void process_browse_packet(struct packet_struct *p,char *buf,int len);
  11601. +void process_dgram(struct packet_struct *p);
  11602. +BOOL reload_services(BOOL test);
  11603. +void debug_nmb_packet(struct packet_struct *p);
  11604. +char *namestr(struct nmb_name *n);
  11605. +void free_nmb_packet(struct nmb_packet *nmb);
  11606. +void free_packet(struct packet_struct *packet);
  11607. +struct packet_struct *read_packet(int fd,enum packet_type packet_type);
  11608. +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
  11609. +BOOL send_packet(struct packet_struct *p);
  11610. +struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
  11611. +int main(int argc,char *argv[]);
  11612. +char *getsmbpass(char *pass);
  11613. +void sync_browse_lists(struct work_record *work, char *name, int nm_type,
  11614. +               struct in_addr ip);
  11615. +BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *));
  11616. +void generate_next_challenge(char *challenge);
  11617. +BOOL set_challenge(char *challenge);
  11618. +BOOL last_challenge(char *challenge);
  11619. +int valid_uid(int uid);
  11620. +user_struct *get_valid_user_struct(int uid);
  11621. +void invalidate_uid(int uid);
  11622. +char *validated_username(int vuid);
  11623. +void register_uid(int uid,int gid, char *name,BOOL guest);
  11624. +void add_session_user(char *user);
  11625. +void dfs_unlogin(void);
  11626. +BOOL password_check(char *password);
  11627. +BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
  11628. +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL is_nt_password);
  11629. +BOOL user_ok(char *user,int snum);
  11630. +BOOL authorise_login(int snum,char *user,char *password, int pwlen, 
  11631. +             BOOL *guest,BOOL *force,int vuid);
  11632. +BOOL check_hosts_equiv(char *user);
  11633. +BOOL server_cryptkey(char *buf);
  11634. +BOOL server_validate(char *buf);
  11635. +BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
  11636. +void pcap_printer_fn(void (*fn)());
  11637. +void lpq_reset(int snum);
  11638. +void print_file(int fnum);
  11639. +int get_printqueue(int snum,int cnum,print_queue_struct **queue,
  11640. +           print_status_struct *status);
  11641. +void del_printqueue(int cnum,int snum,int jobid);
  11642. +void status_printjob(int cnum,int snum,int jobid,int status);
  11643. +int reply_special(char *inbuf,char *outbuf);
  11644. +int reply_tcon(char *inbuf,char *outbuf);
  11645. +int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
  11646. +int reply_unknown(char *inbuf,char *outbuf);
  11647. +int reply_ioctl(char *inbuf,char *outbuf);
  11648. +int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize);
  11649. +int reply_chkpth(char *inbuf,char *outbuf);
  11650. +int reply_getatr(char *inbuf,char *outbuf);
  11651. +int reply_setatr(char *inbuf,char *outbuf);
  11652. +int reply_dskattr(char *inbuf,char *outbuf);
  11653. +int reply_search(char *inbuf,char *outbuf);
  11654. +int reply_fclose(char *inbuf,char *outbuf);
  11655. +int reply_open(char *inbuf,char *outbuf);
  11656. +int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize);
  11657. +int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize);
  11658. +int reply_mknew(char *inbuf,char *outbuf);
  11659. +int reply_ctemp(char *inbuf,char *outbuf);
  11660. +int reply_unlink(char *inbuf,char *outbuf);
  11661. +int reply_readbraw(char *inbuf, char *outbuf);
  11662. +int reply_lockread(char *inbuf,char *outbuf);
  11663. +int reply_read(char *inbuf,char *outbuf);
  11664. +int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
  11665. +int reply_writebraw(char *inbuf,char *outbuf);
  11666. +int reply_writeunlock(char *inbuf,char *outbuf);
  11667. +int reply_write(char *inbuf,char *outbuf,int dum1,int dum2);
  11668. +int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
  11669. +int reply_lseek(char *inbuf,char *outbuf);
  11670. +int reply_flush(char *inbuf,char *outbuf);
  11671. +int reply_exit(char *inbuf,char *outbuf);
  11672. +int reply_close(char *inbuf,char *outbuf);
  11673. +int reply_writeclose(char *inbuf,char *outbuf);
  11674. +int reply_lock(char *inbuf,char *outbuf);
  11675. +int reply_unlock(char *inbuf,char *outbuf);
  11676. +int reply_tdis(char *inbuf,char *outbuf);
  11677. +int reply_echo(char *inbuf,char *outbuf);
  11678. +int reply_printopen(char *inbuf,char *outbuf);
  11679. +int reply_printclose(char *inbuf,char *outbuf);
  11680. +int reply_printqueue(char *inbuf,char *outbuf);
  11681. +int reply_printwrite(char *inbuf,char *outbuf);
  11682. +int reply_mkdir(char *inbuf,char *outbuf);
  11683. +int reply_rmdir(char *inbuf,char *outbuf);
  11684. +int reply_mv(char *inbuf,char *outbuf);
  11685. +int reply_copy(char *inbuf,char *outbuf);
  11686. +int reply_setdir(char *inbuf,char *outbuf);
  11687. +int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize);
  11688. +int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize);
  11689. +int reply_writebmpx(char *inbuf,char *outbuf);
  11690. +int reply_writebs(char *inbuf,char *outbuf);
  11691. +int reply_setattrE(char *inbuf,char *outbuf);
  11692. +int reply_getattrE(char *inbuf,char *outbuf);
  11693. +mode_t unix_mode(int cnum,int dosmode);
  11694. +int dos_mode(int cnum,char *path,struct stat *sbuf);
  11695. +int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
  11696. +BOOL unix_convert(char *name,int cnum);
  11697. +int disk_free(char *path,int *bsize,int *dfree,int *dsize);
  11698. +int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
  11699. +BOOL check_name(char *name,int cnum);
  11700. +void open_file(int fnum,int cnum,char *fname1,int flags,int mode);
  11701. +void sync_file(int fnum);
  11702. +void close_file(int fnum);
  11703. +BOOL check_file_sharing(int cnum,char *fname);
  11704. +void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
  11705. +              int mode,int *Access,int *action);
  11706. +int seek_file(int fnum,int pos);
  11707. +int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL exact);
  11708. +int write_file(int fnum,char *data,int n);
  11709. +BOOL become_service(int cnum,BOOL do_chdir);
  11710. +int find_service(char *service);
  11711. +int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
  11712. +int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
  11713. +int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
  11714. +BOOL snum_used(int snum);
  11715. +BOOL reload_services(BOOL test);
  11716. +int setup_groups(char *user, int uid, int gid, int *p_ngroups, 
  11717. +         int **p_igroups, gid_t **p_groups);
  11718. +int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid);
  11719. +int find_free_file(void );
  11720. +int reply_corep(char *outbuf);
  11721. +int reply_coreplus(char *outbuf);
  11722. +int reply_lanman1(char *outbuf);
  11723. +int reply_lanman2(char *outbuf);
  11724. +int reply_nt1(char *outbuf);
  11725. +void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev);
  11726. +void close_cnum(int cnum, int uid);
  11727. +BOOL yield_connection(int cnum,char *name,int max_connections);
  11728. +BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
  11729. +void exit_server(char *reason);
  11730. +void standard_sub(int cnum,char *s);
  11731. +char *smb_fn_name(int type);
  11732. +int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
  11733. +int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
  11734. +void str_to_key(uchar *str,uchar *key);
  11735. +void D1(uchar *k, uchar *d, uchar *out);
  11736. +void E1(uchar *k, uchar *d, uchar *out);
  11737. +void E_P16(uchar *p14,uchar *p16);
  11738. +void E_P24(uchar *p21, uchar *c8, uchar *p24);
  11739. +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
  11740. +void E_md4hash(uchar *passwd, uchar *p16);
  11741. +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
  11742. +void Ucrit_addUsername(pstring username);
  11743. +unsigned int Ucrit_checkUsername(pstring username);
  11744. +void Ucrit_addPid(int pid);
  11745. +unsigned int   Ucrit_checkPid(int pid);
  11746. +int sys_select(fd_set *fds,struct timeval *tval);
  11747. +int sys_select(fd_set *fds,struct timeval *tval);
  11748. +int sys_unlink(char *fname);
  11749. +int sys_open(char *fname,int flags,int mode);
  11750. +DIR *sys_opendir(char *dname);
  11751. +int sys_stat(char *fname,struct stat *sbuf);
  11752. +int sys_lstat(char *fname,struct stat *sbuf);
  11753. +int sys_mkdir(char *dname,int mode);
  11754. +int sys_rmdir(char *dname);
  11755. +int sys_chdir(char *dname);
  11756. +int sys_utime(char *fname,struct utimbuf *times);
  11757. +int sys_rename(char *from, char *to);
  11758. +int sys_chown(char *fname,int uid,int gid);
  11759. +int sys_chroot(char *dname);
  11760. +int main(int argc, char *argv[]);
  11761. +void GetTimeOfDay(struct timeval *tval);
  11762. +void TimeInit(void);
  11763. +int TimeDiff(time_t t);
  11764. +struct tm *LocalTime(time_t *t);
  11765. +time_t interpret_long_date(char *p);
  11766. +void put_long_date(char *p,time_t t);
  11767. +void put_dos_date(char *buf,int offset,time_t unixdate);
  11768. +void put_dos_date2(char *buf,int offset,time_t unixdate);
  11769. +void put_dos_date3(char *buf,int offset,time_t unixdate);
  11770. +time_t make_unix_date(void *date_ptr);
  11771. +time_t make_unix_date2(void *date_ptr);
  11772. +time_t make_unix_date3(void *date_ptr);
  11773. +BOOL set_filetime(char *fname,time_t mtime);
  11774. +char *timestring(void );
  11775. +int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
  11776. +int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
  11777. +int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
  11778. +int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
  11779. +char *ufc_crypt(char *key,char *salt);
  11780. +void init_uid(void);
  11781. +BOOL become_guest(void);
  11782. +BOOL become_user(int cnum, int uid);
  11783. +BOOL unbecome_user(void );
  11784. +int smbrun(char *cmd,char *outfile);
  11785. +char *get_home_dir(char *user);
  11786. +void map_username(char *user);
  11787. +struct passwd *Get_Pwnam(char *user,BOOL allow_change);
  11788. +BOOL user_in_list(char *user,char *list);
  11789. +void setup_logging(char *pname,BOOL interactive);
  11790. +void reopen_logs(void);
  11791. +BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
  11792. +int file_lock(char *name,int timeout);
  11793. +void file_unlock(int fd);
  11794. +BOOL is_a_socket(int fd);
  11795. +BOOL next_token(char **ptr,char *buff,char *sep);
  11796. +char **toktocliplist(int *ctok, char *sep);
  11797. +void *MemMove(void *dest,void *src,int size);
  11798. +void array_promote(char *array,int elsize,int element);
  11799. +void set_socket_options(int fd, char *options);
  11800. +void close_sockets(void );
  11801. +BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups);
  11802. +char *StrCpy(char *dest,char *src);
  11803. +char *StrnCpy(char *dest,const char *src,int n);
  11804. +void putip(void *dest,void *src);
  11805. +int name_mangle(char *In,char *Out,char name_type);
  11806. +BOOL file_exist(char *fname,struct stat *sbuf);
  11807. +time_t file_modtime(char *fname);
  11808. +BOOL directory_exist(char *dname,struct stat *st);
  11809. +uint32 file_size(char *file_name);
  11810. +char *attrib_string(int mode);
  11811. +int StrCaseCmp(char *s, char *t);
  11812. +int StrnCaseCmp(char *s, char *t, int n);
  11813. +BOOL strequal(char *s1,char *s2);
  11814. +BOOL strnequal(char *s1,char *s2,int n);
  11815. +BOOL strcsequal(char *s1,char *s2);
  11816. +void strlower(char *s);
  11817. +void strupper(char *s);
  11818. +void strnorm(char *s);
  11819. +BOOL strisnormal(char *s);
  11820. +void string_replace(char *s,char oldc,char newc);
  11821. +void unix_format(char *fname);
  11822. +void dos_format(char *fname);
  11823. +void show_msg(char *buf);
  11824. +int smb_len(char *buf);
  11825. +void _smb_setlen(char *buf,int len);
  11826. +void smb_setlen(char *buf,int len);
  11827. +int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
  11828. +int smb_numwords(char *buf);
  11829. +int smb_buflen(char *buf);
  11830. +int smb_buf_ofs(char *buf);
  11831. +char *smb_buf(char *buf);
  11832. +int smb_offset(char *p,char *buf);
  11833. +char *skip_string(char *buf,int n);
  11834. +BOOL trim_string(char *s,char *front,char *back);
  11835. +void dos_clean_name(char *s);
  11836. +void unix_clean_name(char *s);
  11837. +int ChDir(char *path);
  11838. +char *GetWd(char *str);
  11839. +BOOL reduce_name(char *s,char *dir,BOOL widelinks);
  11840. +void expand_mask(char *Mask,BOOL doext);
  11841. +BOOL strhasupper(char *s);
  11842. +BOOL strhaslower(char *s);
  11843. +int count_chars(char *s,char c);
  11844. +void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
  11845. +void close_low_fds(void);
  11846. +int write_socket(int fd,char *buf,int len);
  11847. +int read_udp_socket(int fd,char *buf,int len);
  11848. +int set_blocking(int fd, BOOL set);
  11849. +int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact);
  11850. +int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
  11851. +int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
  11852. +BOOL send_keepalive(int client);
  11853. +int read_data(int fd,char *buffer,int N);
  11854. +int write_data(int fd,char *buffer,int N);
  11855. +int read_predict(int fd,int offset,char *buf,char **ptr,int num);
  11856. +void do_read_prediction();
  11857. +void invalidate_read_prediction(int fd);
  11858. +int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
  11859. +int read_smb_length(int fd,char *inbuf,int timeout);
  11860. +BOOL receive_smb(int fd,char *buffer,int timeout);
  11861. +BOOL send_smb(int fd,char *buffer);
  11862. +char *name_ptr(char *buf,int ofs);
  11863. +int name_extract(char *buf,int ofs,char *name);
  11864. +int name_len(char *s);
  11865. +BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
  11866. +void msleep(int t);
  11867. +BOOL in_list(char *s,char *list,BOOL casesensitive);
  11868. +BOOL string_init(char **dest,char *src);
  11869. +void string_free(char **s);
  11870. +BOOL string_set(char **dest,char *src);
  11871. +BOOL string_sub(char *s,char *pattern,char *insert);
  11872. +BOOL do_match(char *str, char *regexp, int case_sig);
  11873. +BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2);
  11874. +void become_daemon(void);
  11875. +void get_broadcast(struct in_addr *if_ipaddr,
  11876. +                    struct in_addr *if_bcast,
  11877. +                    struct in_addr *if_nmask);
  11878. +BOOL yesno(char *p);
  11879. +char *fgets_slash(char *s2,int maxlen,FILE *f);
  11880. +int set_filelen(int fd, long len);
  11881. +int byte_checksum(char *buf,int len);
  11882. +void setbuffer(FILE *f,char *buf,int bufsize);
  11883. +char *dirname_dos(char *path,char *buf);
  11884. +void *Realloc(void *p,int size);
  11885. +void Abort(void );
  11886. +BOOL get_myname(char *myname,struct in_addr *ip);
  11887. +BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
  11888. +int open_socket_in(int type, int port, int dlevel);
  11889. +int open_socket_out(int type, struct in_addr *addr, int port );
  11890. +int interpret_protocol(char *str,int def);
  11891. +int interpret_security(char *str,int def);
  11892. +unsigned long interpret_addr(char *str);
  11893. +struct in_addr *interpret_addr2(char *str);
  11894. +BOOL zero_ip(struct in_addr ip);
  11895. +void standard_sub_basic(char *s);
  11896. +BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
  11897. +int PutUniCode(char *dst,char *src);
  11898. +struct hostent *Get_Hostbyname(char *name);
  11899. +BOOL process_exists(int pid);
  11900. +char *uidtoname(int uid);
  11901. +char *gidtoname(int gid);
  11902. +void BlockSignals(BOOL block);
  11903. +void ajt_panic(void);
  11904. +char *readdirname(void *p);
  11905. +void *malloc_wrapped(int size,char *file,int line);
  11906. +void *realloc_wrapped(void *ptr,int size,char *file,int line);
  11907. +void free_wrapped(void *ptr,char *file,int line);
  11908. +char *Strstr(char *s, char *p);
  11909. +time_t Mktime(struct tm      *t);
  11910. +int InNetGr(char *group,char *host,char *user,char *dom);
  11911. +void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
  11912. +int    VT_Check(char    *buffer);
  11913. +int VT_Start_utmp(void);
  11914. +int VT_Stop_utmp(void);
  11915. +void    VT_AtExit(void);
  11916. +void    VT_SigCLD(int    sig);
  11917. +void    VT_SigEXIT(int    sig);
  11918. +int    VT_Start(void);
  11919. +int    VT_Output(char    *Buffer);
  11920. +int    VT_Input(char    *Buffer,int        Size);
  11921. +void VT_Process(void);
  11922. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/quotas.c samba-1.9.16alpha5/source/quotas.c
  11923. --- samba-1.9.16alpha4/source/quotas.c    Sat Jun  1 01:15:12 1996
  11924. +++ samba-1.9.16alpha5/source/quotas.c    Wed Jun  5 01:16:28 1996
  11925. @@ -355,5 +355,9 @@
  11926.  }
  11927.  
  11928.  #endif
  11929. +
  11930. +#else
  11931. +/* this keeps fussy compilers happy */
  11932. + void quotas_dummy(void) {}
  11933.  #endif /* QUOTAS */
  11934.  
  11935. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/reply.c samba-1.9.16alpha5/source/reply.c
  11936. --- samba-1.9.16alpha4/source/reply.c    Sat Jun  1 01:15:12 1996
  11937. +++ samba-1.9.16alpha5/source/reply.c    Wed Jun  5 01:16:28 1996
  11938. @@ -1928,11 +1928,11 @@
  11939.  
  11940.    mtime = make_unix_date3(inbuf+smb_vwv1);
  11941.  
  11942. -  close_file(fnum);
  11943. -
  11944.    /* try and set the date */
  11945.    set_filetime(Files[fnum].name,mtime);
  11946.  
  11947. +  close_file(fnum);
  11948. +
  11949.    /* We have a cached error */
  11950.    if(eclass || err)
  11951.      return(ERROR(eclass,err));
  11952. @@ -1976,10 +1976,10 @@
  11953.        
  11954.    nwritten = write_file(fnum,data,numtowrite);
  11955.  
  11956. -  close_file(fnum);
  11957. -
  11958.    set_filetime(Files[fnum].name,mtime);
  11959.    
  11960. +  close_file(fnum);
  11961. +
  11962.    DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
  11963.         timestring(),fnum,cnum,numtowrite,nwritten,
  11964.         Connections[cnum].num_files_open));
  11965. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/server.c samba-1.9.16alpha5/source/server.c
  11966. --- samba-1.9.16alpha4/source/server.c    Sat Jun  1 01:15:12 1996
  11967. +++ samba-1.9.16alpha5/source/server.c    Wed Jun  5 01:16:29 1996
  11968. @@ -26,7 +26,6 @@
  11969.  #include "reply.h"
  11970.  
  11971.  pstring servicesf = CONFIGFILE;
  11972. -pstring OriginalDir ="/";
  11973.  extern pstring debugf;
  11974.  extern pstring sesssetup_user;
  11975.  
  11976. @@ -34,16 +33,8 @@
  11977.  char *OutBuffer = NULL;
  11978.  char *last_inbuf = NULL;
  11979.  
  11980. -int initial_uid = 0;
  11981. -int initial_gid = 0;
  11982. -
  11983.  BOOL share_mode_pending = False;
  11984.  
  11985. -/* have I done a become_user? */
  11986. -static struct {
  11987. -  int cnum, uid;
  11988. -} last_user;
  11989. -
  11990.  /* the last message the was processed */
  11991.  int last_message = -1;
  11992.  
  11993. @@ -148,31 +139,20 @@
  11994.  int dos_mode(int cnum,char *path,struct stat *sbuf)
  11995.  {
  11996.    int result = 0;
  11997. +  extern struct current_user current_user;
  11998.  
  11999. -#if OLD_DOS_MODE
  12000. -  if (!CAN_WRITE(cnum) || !((sbuf->st_mode & S_IWOTH) ||
  12001. -                Connections[cnum].admin_user ||
  12002. -                ((sbuf->st_mode & S_IWUSR) && 
  12003. -                 Connections[cnum].uid==sbuf->st_uid) ||
  12004. -                ((sbuf->st_mode & S_IWGRP) && 
  12005. -                 in_group(sbuf->st_gid,Connections[cnum].gid,
  12006. -                      Connections[cnum].ngroups,
  12007. -                      Connections[cnum].igroups))))
  12008. -    result |= aRONLY;
  12009. -#else
  12010.    if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
  12011.      if (!((sbuf->st_mode & S_IWOTH) ||
  12012.        Connections[cnum].admin_user ||
  12013. -      ((sbuf->st_mode & S_IWUSR) && Connections[cnum].uid==sbuf->st_uid) ||
  12014. +      ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
  12015.        ((sbuf->st_mode & S_IWGRP) && 
  12016. -       in_group(sbuf->st_gid,Connections[cnum].gid,
  12017. -            Connections[cnum].ngroups,Connections[cnum].igroups))))
  12018. +       in_group(sbuf->st_gid,current_user.gid,
  12019. +            current_user.ngroups,current_user.igroups))))
  12020.        result |= aRONLY;
  12021.    } else {
  12022.      if ((sbuf->st_mode & S_IWUSR) == 0)
  12023.        result |= aRONLY;
  12024.    }
  12025. -#endif
  12026.  
  12027.    if ((sbuf->st_mode & S_IXUSR) != 0)
  12028.      result |= aARCH;
  12029. @@ -1373,8 +1353,6 @@
  12030.  }
  12031.  
  12032.  
  12033. -static int old_umask = 022;
  12034. -
  12035.  /****************************************************************************
  12036.  load parameters specific to a connection/service
  12037.  ****************************************************************************/
  12038. @@ -1420,261 +1398,6 @@
  12039.  
  12040.  
  12041.  /****************************************************************************
  12042. -  become the specified uid 
  12043. -****************************************************************************/
  12044. -static BOOL become_uid(int uid)
  12045. -{
  12046. -  if (initial_uid != 0)
  12047. -    return(True);
  12048. -
  12049. -#ifdef AIX
  12050. -  {
  12051. -    /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */
  12052. -    priv_t priv;
  12053. -
  12054. -    priv.pv_priv[0] = 0;
  12055. -    priv.pv_priv[1] = 0;
  12056. -    if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH,
  12057. -        &priv, sizeof(priv_t)) < 0 ||
  12058. -    setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 ||
  12059. -    seteuid((uid_t)uid) < 0) 
  12060. -      DEBUG(1,("Can't set uid (AIX3)"));
  12061. -  }
  12062. -#endif
  12063. -
  12064. -#ifdef USE_SETRES
  12065. -  if (setresuid(-1,uid,-1) != 0)
  12066. -#else
  12067. -    if ((seteuid(uid) != 0) && 
  12068. -    (setuid(uid) != 0))
  12069. -#endif
  12070. -      {
  12071. -    DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
  12072. -         uid,getuid(), geteuid()));
  12073. -    if (uid > 32000)
  12074. -      DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
  12075. -    return(False);
  12076. -      }
  12077. -
  12078. -  if (((uid == -1) || (uid == 65535)) && geteuid() != uid)
  12079. -    {
  12080. -      DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
  12081. -      return(False);
  12082. -    }
  12083. -
  12084. -  return(True);
  12085. -}
  12086. -
  12087. -
  12088. -/****************************************************************************
  12089. -  become the specified gid
  12090. -****************************************************************************/
  12091. -static BOOL become_gid(int gid)
  12092. -{
  12093. -  if (initial_uid != 0)
  12094. -    return(True);
  12095. -  
  12096. -#ifdef USE_SETRES 
  12097. -  if (setresgid(-1,gid,-1) != 0)
  12098. -#else
  12099. -    if (setgid(gid) != 0)
  12100. -#endif
  12101. -      {
  12102. -    DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
  12103. -         gid,getgid(),getegid()));
  12104. -    if (gid > 32000)
  12105. -      DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
  12106. -    return(False);
  12107. -      }
  12108. -
  12109. -  return(True);
  12110. -}
  12111. -
  12112. -
  12113. -/****************************************************************************
  12114. -  become the specified uid and gid
  12115. -****************************************************************************/
  12116. -static BOOL become_id(int uid,int gid)
  12117. -{
  12118. -  return(become_gid(gid) && become_uid(uid));
  12119. -}
  12120. -
  12121. -/****************************************************************************
  12122. -become the guest user
  12123. -****************************************************************************/
  12124. -static BOOL become_guest(void)
  12125. -{
  12126. -  BOOL ret;
  12127. -  static struct passwd *pass=NULL;
  12128. -
  12129. -  if (initial_uid != 0) 
  12130. -    return(True);
  12131. -
  12132. -  if (!pass)
  12133. -    pass = Get_Pwnam(lp_guestaccount(-1),True);
  12134. -  if (!pass) return(False);
  12135. -
  12136. -  ret = become_id(pass->pw_uid,pass->pw_gid);
  12137. -
  12138. -  if (!ret)
  12139. -    DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
  12140. -
  12141. -  last_user.cnum = -2;
  12142. -
  12143. -  return(ret);
  12144. -}
  12145. -
  12146. -/*******************************************************************
  12147. -check if a username is OK
  12148. -********************************************************************/
  12149. -static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
  12150. -{
  12151. -  int i;
  12152. -  for (i=0;i<Connections[cnum].uid_cache.entries;i++)
  12153. -    if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True);
  12154. -
  12155. -  if (!user_ok(vuser->name,snum)) return(False);
  12156. -
  12157. -  i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE;
  12158. -  Connections[cnum].uid_cache.list[i] = vuser->uid;
  12159. -
  12160. -  if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE)
  12161. -    Connections[cnum].uid_cache.entries++;
  12162. -
  12163. -  return(True);
  12164. -}
  12165. -
  12166. -
  12167. -/****************************************************************************
  12168. -  become the user of a connection number
  12169. -****************************************************************************/
  12170. -BOOL become_user(int cnum, int uid)
  12171. -{
  12172. -  int new_umask;
  12173. -  user_struct *vuser;
  12174. -  int snum,gid;
  12175. -  int ngroups;
  12176. -  gid_t *groups;
  12177. -
  12178. -  if (last_user.cnum == cnum && last_user.uid == uid) {
  12179. -    DEBUG(4,("Skipping become_user - already user\n"));
  12180. -    return(True);
  12181. -  }
  12182. -
  12183. -  unbecome_user();
  12184. -
  12185. -  if (!OPEN_CNUM(cnum)) {
  12186. -    DEBUG(2,("Connection %d not open\n",cnum));
  12187. -    return(False);
  12188. -  }
  12189. -
  12190. -  snum = Connections[cnum].service;
  12191. -
  12192. -  if (Connections[cnum].force_user || 
  12193. -      lp_security() == SEC_SHARE ||
  12194. -      !(vuser = get_valid_user_struct(uid)) ||
  12195. -      !check_user_ok(cnum,vuser,snum)) {
  12196. -    uid = Connections[cnum].uid;
  12197. -    gid = Connections[cnum].gid;
  12198. -    groups = Connections[cnum].groups;
  12199. -    ngroups = Connections[cnum].ngroups;
  12200. -  } else {
  12201. -    if (!vuser) {
  12202. -      DEBUG(2,("Invalid vuid used %d\n",uid));
  12203. -      return(False);
  12204. -    }
  12205. -    uid = vuser->uid;
  12206. -    if(!*lp_force_group(snum))
  12207. -      gid = vuser->gid;
  12208. -    else
  12209. -      gid = Connections[cnum].gid;
  12210. -    groups = vuser->user_groups;
  12211. -    ngroups = vuser->user_ngroups;
  12212. -  }
  12213. -
  12214. -  if (initial_uid == 0)
  12215. -    {
  12216. -      if (!become_gid(gid)) return(False);
  12217. -
  12218. -#ifndef NO_SETGROUPS      
  12219. -      if (!IS_IPC(cnum)) {
  12220. -    /* groups stuff added by ih/wreu */
  12221. -    if (ngroups > 0)
  12222. -      if (setgroups(ngroups,groups)<0)
  12223. -        DEBUG(0,("setgroups call failed!\n"));
  12224. -      }
  12225. -#endif
  12226. -
  12227. -      if (!Connections[cnum].admin_user && !become_uid(uid))
  12228. -    return(False);
  12229. -    }
  12230. -
  12231. -  new_umask = 0777 & ~CREATE_MODE(cnum);
  12232. -  old_umask = umask(new_umask);
  12233. -
  12234. -  last_user.cnum = cnum;
  12235. -  last_user.uid = uid;
  12236. -  
  12237. -  DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n",
  12238. -       getuid(),geteuid(),getgid(),getegid(),new_umask));
  12239. -  
  12240. -  return(True);
  12241. -}
  12242. -
  12243. -/****************************************************************************
  12244. -  unbecome the user of a connection number
  12245. -****************************************************************************/
  12246. -BOOL unbecome_user(void )
  12247. -{
  12248. -  if (last_user.cnum == -1)
  12249. -    return(False);
  12250. -
  12251. -  ChDir(OriginalDir);
  12252. -
  12253. -  umask(old_umask);
  12254. -
  12255. -  if (initial_uid == 0)
  12256. -    {
  12257. -#ifdef USE_SETRES
  12258. -      setresuid(-1,getuid(),-1);
  12259. -      setresgid(-1,getgid(),-1);
  12260. -#else
  12261. -      if (seteuid(initial_uid) != 0) 
  12262. -    setuid(initial_uid);
  12263. -      setgid(initial_gid);
  12264. -#endif
  12265. -    }
  12266. -#ifdef NO_EID
  12267. -  if (initial_uid == 0)
  12268. -    DEBUG(2,("Running with no EID\n"));
  12269. -  initial_uid = getuid();
  12270. -  initial_gid = getgid();
  12271. -#else
  12272. -  if (geteuid() != initial_uid)
  12273. -    {
  12274. -      DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
  12275. -      initial_uid = geteuid();
  12276. -    }
  12277. -  if (getegid() != initial_gid)
  12278. -    {
  12279. -      DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
  12280. -      initial_gid = getegid();
  12281. -    }
  12282. -#endif
  12283. -  
  12284. -  if (ChDir(OriginalDir) != 0)
  12285. -    DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
  12286. -         timestring(),OriginalDir));  
  12287. -
  12288. -  DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
  12289. -    getuid(),geteuid(),getgid(),getegid()));
  12290. -
  12291. -  last_user.cnum = -1;
  12292. -
  12293. -  return(True);
  12294. -}
  12295. -
  12296. -/****************************************************************************
  12297.    find a service entry
  12298.  ****************************************************************************/
  12299.  int find_service(char *service)
  12300. @@ -3649,7 +3372,7 @@
  12301.  /****************************************************************************
  12302.    process commands from the client
  12303.  ****************************************************************************/
  12304. -void process(void )
  12305. +static void process(void)
  12306.  {
  12307.    static int trans_num = 0;
  12308.    int nread;
  12309. @@ -3673,12 +3396,10 @@
  12310.      ip = *interpret_addr2("localhost");
  12311.      if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
  12312.      *OutBuffer = 0;
  12313. -    send_one_packet(OutBuffer,1,ip,137,SOCK_DGRAM);
  12314. +    send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
  12315.    }
  12316.  #endif    
  12317.  
  12318. -  last_user.cnum = -1;
  12319. -  
  12320.    while (True)
  12321.      {
  12322.        int32 len;      
  12323. @@ -3860,7 +3581,7 @@
  12324.  /****************************************************************************
  12325.  usage on the program
  12326.  ****************************************************************************/
  12327. -void usage(char *pname)
  12328. +static void usage(char *pname)
  12329.  {
  12330.    DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
  12331.  
  12332. @@ -3880,12 +3601,12 @@
  12333.  /****************************************************************************
  12334.    main program
  12335.  ****************************************************************************/
  12336. -int main(int argc,char *argv[])
  12337. + int main(int argc,char *argv[])
  12338.  {
  12339.    extern BOOL append_log;
  12340.    /* shall I run as a daemon */
  12341.    BOOL is_daemon = False;
  12342. -  int port = 139;
  12343. +  int port = SMB_PORT;
  12344.    int opt;
  12345.    extern char *optarg;
  12346.  
  12347. @@ -3922,22 +3643,7 @@
  12348.  
  12349.    umask(0777 & ~DEF_CREATE_MASK);
  12350.  
  12351. -  initial_uid = geteuid();
  12352. -  initial_gid = getegid();
  12353. -
  12354. -  if (initial_gid != 0 && initial_uid == 0)
  12355. -    {
  12356. -#ifdef HPUX
  12357. -      setresgid(0,0,0);
  12358. -#else
  12359. -      setgid(0);
  12360. -      setegid(0);
  12361. -#endif
  12362. -    }
  12363. -
  12364. -  initial_uid = geteuid();
  12365. -  initial_gid = getegid();
  12366. -
  12367. +  init_uid();
  12368.  
  12369.    /* this is for people who can't start the program correctly */
  12370.    while (argc > 1 && (*argv[1] != '-'))
  12371. @@ -3998,8 +3704,6 @@
  12372.  
  12373.    DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
  12374.    DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
  12375. -
  12376. -  GetWd(OriginalDir);
  12377.  
  12378.  #ifndef NO_GETRLIMIT
  12379.  #ifdef RLIMIT_NOFILE
  12380. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/smb.h samba-1.9.16alpha5/source/smb.h
  12381. --- samba-1.9.16alpha4/source/smb.h    Sat Jun  1 01:15:12 1996
  12382. +++ samba-1.9.16alpha5/source/smb.h    Wed Jun  5 01:16:29 1996
  12383. @@ -40,6 +40,10 @@
  12384.  #    define EXTERN extern
  12385.  #endif
  12386.  
  12387. +#define NMB_PORT 137
  12388. +#define DGRAM_PORT 138
  12389. +#define SMB_PORT 139
  12390. +
  12391.  #define False (0)
  12392.  #define True (1)
  12393.  #define BOOLSTR(b) ((b) ? "Yes" : "No")
  12394. @@ -72,6 +76,19 @@
  12395.  typedef unsigned int uint32;
  12396.  #endif
  12397.  
  12398. +#ifndef uchar
  12399. +#define uchar unsigned char
  12400. +#endif
  12401. +#ifndef int16
  12402. +#define int16 short
  12403. +#endif
  12404. +#ifndef uint16
  12405. +#define uint16 unsigned short
  12406. +#endif
  12407. +#ifndef uint32
  12408. +#define uint32 unsigned int
  12409. +#endif
  12410. +
  12411.  #define SIZEOFWORD 2
  12412.  
  12413.  #ifndef DEF_CREATE_MASK
  12414. @@ -216,6 +233,15 @@
  12415.  typedef char fstring[128];
  12416.  typedef fstring string;
  12417.  
  12418. +
  12419. +struct current_user {
  12420. +  int cnum, id;
  12421. +  int uid, gid;
  12422. +  int ngroups;
  12423. +  gid_t *groups;
  12424. +  int *igroups;
  12425. +};
  12426. +
  12427.  typedef struct
  12428.  {
  12429.    int size;
  12430. @@ -332,6 +358,16 @@
  12431.    int status;
  12432.  }  print_status_struct;
  12433.  
  12434. +/* used for server information: client, nameserv and ipc */
  12435. +struct server_info_struct
  12436. +{
  12437. +  fstring name;
  12438. +  uint32 type;
  12439. +  fstring comment;
  12440. +  fstring domain; /* used ONLY in ipc.c NOT namework.c */
  12441. +  BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
  12442. +};
  12443. +
  12444.  
  12445.  /* this is used for smbstatus */
  12446.  struct connect_record
  12447. @@ -582,279 +618,29 @@
  12448.      struct sockaddr_in *sin;        /* their side of the link */
  12449.  };
  12450.  
  12451. -/* and a few prototypes */
  12452. -BOOL user_ok(char *user,int snum);
  12453. -int sys_rename(char *from, char *to);
  12454. -int sys_select(fd_set *fds,struct timeval *tval);
  12455. -int sys_unlink(char *fname);
  12456. -int sys_open(char *fname,int flags,int mode);
  12457. -DIR *sys_opendir(char *dname);
  12458. -int sys_stat(char *fname,struct stat *sbuf);
  12459. -int sys_lstat(char *fname,struct stat *sbuf);
  12460. -int sys_mkdir(char *dname,int mode);
  12461. -int sys_rmdir(char *dname);
  12462. -int sys_chdir(char *dname);
  12463. -int sys_utime(char *fname,struct utimbuf *times);
  12464. -int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
  12465. -void lpq_reset(int);
  12466. -void status_printjob(int cnum,int snum,int jobid,int status);
  12467. -void DirCacheAdd(char *path,char *name,char *dname,int snum);
  12468. -char *DirCacheCheck(char *path,char *name,int snum);
  12469. -void DirCacheFlush(int snum);
  12470. -int interpret_character_set(char *str, int def);
  12471. -char *dos2unix_format(char *, BOOL);
  12472. -char *unix2dos_format(char *, BOOL);
  12473. -BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
  12474. -void BlockSignals(BOOL block);
  12475. -void msleep(int t);
  12476. -int file_lock(char *name,int timeout);
  12477. -void file_unlock(int fd);
  12478. -int find_service(char *service);
  12479. -int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
  12480. -int smb_offset(char *p,char *buf);
  12481. -void sync_file(int fnum);
  12482. -int PutUniCode(char *dst,char *src);
  12483. -void map_username(char *user);
  12484. -void close_low_fds(void);
  12485. -void clean_share_files(void);
  12486. -int write_socket(int fd,char *buf,int len);
  12487. -char *readdirname(void *p);
  12488. -int dos_chmod(int cnum,char *fname,int mode,struct stat *st);
  12489. -int smb_numwords(char *buf);
  12490. -int get_share_mode(int cnum,struct stat *sbuf,int *pid);
  12491. -void del_share_mode(int fnum);
  12492. -BOOL set_share_mode(int fnum,int mode);
  12493. -void TimeInit(void);
  12494. -void put_long_date(char *p,time_t t);
  12495. -time_t interpret_long_date(char *p);
  12496. -void dptr_idlecnum(int cnum);
  12497. -void dptr_closecnum(int cnum);
  12498. -void init_dptrs(void);
  12499. -void fault_setup();
  12500. -void set_socket_options(int fd, char *options);
  12501. -void putip(void *dest,void *src);
  12502. -void standard_sub_basic(char *s);
  12503. -void *OpenDir(char *name);
  12504. -void CloseDir(void *p);
  12505. -char *ReadDirName(void *p);
  12506. -BOOL SeekDir(void *p,int pos);
  12507. -int TellDir(void *p);
  12508. -int write_data(int fd,char *buffer,int N);
  12509. -BOOL server_cryptkey(char *buf);
  12510. -BOOL server_validate(char *buf);
  12511. -BOOL become_service(int cnum,BOOL do_chdir);
  12512. -BOOL snum_used(int snum);
  12513. -BOOL reload_services(BOOL test);
  12514. -void reopen_logs(void);
  12515. -int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
  12516. -int str_checksum(char *s);
  12517. -time_t file_modtime(char *fname);
  12518. -BOOL do_match(char *str, char *regexp, int case_sig);
  12519. -BOOL is_a_socket(int fd);
  12520. -void _smb_setlen(char *buf,int len);
  12521. -void valid_initialise(void);
  12522. -BOOL is_8_3(char *fname);
  12523. -BOOL is_mangled(char *s);
  12524. -void standard_sub(int cnum,char *s);
  12525. -void del_printqueue(int cnum,int snum,int jobid);
  12526. -BOOL strisnormal(char *s);
  12527. -BOOL check_mangled_stack(char *s);
  12528. -int sys_chown(char *fname,int uid,int gid);
  12529. -int sys_chroot(char *dname);
  12530. -BOOL next_token(char **ptr,char *buff,char *sep);
  12531. -void invalidate_uid(int uid);
  12532. -char *fgets_slash(char *s,int maxlen,FILE *f);
  12533. -int read_udp_socket(int fd,char *buf,int len);
  12534. -void exit_server(char *reason);
  12535. -BOOL process_exists(int pid);
  12536. -BOOL chgpasswd(char *name,char *oldpass,char *newpass);
  12537. -void array_promote(char *array,int elsize,int element);
  12538. -void string_replace(char *s,char oldc,char newc);
  12539. -BOOL user_in_list(char *user,char *list);
  12540. -BOOL string_sub(char *s,char *pattern,char *insert);
  12541. -char *StrnCpy(char *dest,const char *src,int n);
  12542. -char *validated_username(int vuid);
  12543. -BOOL set_user_password(char *user,char *oldpass,char *newpass);
  12544. -int smb_buf_ofs(char *buf);
  12545. -char *skip_string(char *buf,int n);
  12546. -BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset);
  12547. -int read_file(int fnum,char *data,int pos,int mincnt,int maxcnt,int timeout,BOOL exact);
  12548. -int write_file(int fnum,char *data,int n);
  12549. -BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
  12550. -int seek_file(int fnum,int pos);
  12551. -BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
  12552. -int get_printqueue(int snum,int cnum,print_queue_struct **queue,print_status_struct *status);
  12553. -void parse_connect(char *buf,char *service,char *user,char *password,int *pwlen,char *dev);
  12554. -int setup_groups(char *user,int uid, int gid, int *p_ngroups, 
  12555. -         int **p_igroups, gid_t **p_groups);
  12556. -int make_connection(char *service,char *user,char *password, int pwlen, char *dev,int vuid);
  12557. -char *dptr_path(int key);
  12558. -char *dptr_wcard(int key);
  12559. -BOOL dptr_set_wcard(int key, char *wcard);
  12560. -BOOL dptr_set_attr(int key, uint16 attr);
  12561. -uint16 dptr_attr(int key);
  12562. -void dptr_close(int key);
  12563. -void dptr_closepath(char *path,int pid);
  12564. -int dptr_create(int cnum,char *path, BOOL expect_close,int pid);
  12565. -BOOL dptr_fill(char *buf,unsigned int key);
  12566. -BOOL dptr_zero(char *buf);
  12567. -void *dptr_fetch(char *buf,int *num);
  12568. -void *dptr_fetch_lanman2(char *params,int dptr_num);
  12569. -BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
  12570. -void open_file(int fnum,int cnum,char *fname,int flags,int mode);
  12571. -void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,int mode,int *Access,int *action);
  12572. -void close_file(int fnum);
  12573. -int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
  12574. -int reply_trans(char *inbuf,char *outbuf);
  12575. -char *ufc_crypt(char *key,char *salt);
  12576. -BOOL authorise_login(int snum,char *user,char *password, int pwlen, 
  12577. -             BOOL *guest,BOOL *force,int vuid);
  12578. -void add_session_user(char *user);
  12579. -int valid_uid(int uid);
  12580. -user_struct *get_valid_user_struct(int uid);
  12581. -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL nt_password);
  12582. -void register_uid(int uid,int gid,char *name,BOOL guest);
  12583. -BOOL fromhost(int sock,struct from_host *f);
  12584. -BOOL strhasupper(char *s);
  12585. -BOOL strhaslower(char *s);
  12586. -int disk_free(char *path,int *bsize,int *dfree,int *dsize);
  12587. -char *uidtoname(int uid);
  12588. -char *gidtoname(int gid);
  12589. -int get_share_mode_byname(int cnum,char *fname,int *pid);
  12590. -int get_share_mode_by_fnum(int cnum,int fnum,int *pid);
  12591. -BOOL check_file_sharing(int cnum,char *fname);
  12592. -char *StrCpy(char *dest,char *src);
  12593. -int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
  12594. -time_t make_unix_date2(void *date_ptr);
  12595. -int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
  12596. -mode_t unix_mode(int cnum,int dosmode);
  12597. -BOOL check_name(char *name,int cnum);
  12598. -int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
  12599. -int find_free_file(void );
  12600. -BOOL unix_convert(char *name,int cnum);
  12601. -void unix_convert_lanman2(char *s,char *home,BOOL case_is_sig);
  12602. -void print_file(int fnum);
  12603. -int read_smb_length(int fd,char *inbuf,int timeout);
  12604. -int read_predict(int fd,int offset,char *buf,char **ptr,int num);
  12605. -void invalidate_read_prediction(int fd);
  12606. -void do_read_prediction();
  12607. -BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
  12608. -BOOL yield_connection(int cnum,char *name,int max_connections);
  12609. -int count_chars(char *s,char c);
  12610. -int smbrun(char *,char *);
  12611. -BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
  12612. -struct hostent *Get_Hostbyname(char *name);
  12613. -struct passwd *Get_Pwnam(char *user,BOOL allow_change);
  12614. -void Abort(void);
  12615. -void *Realloc(void *p,int size);
  12616. -void smb_setlen(char *buf,int len);
  12617. -int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
  12618. -BOOL check_access(int snum);
  12619. -BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups);
  12620. -BOOL string_set(char **dest,char *src);
  12621. -BOOL string_init(char **dest,char *src);
  12622. -void string_free(char **s);
  12623. -char *attrib_string(int mode);
  12624. -void unix_format(char *fname);
  12625. -BOOL directory_exist(char *dname,struct stat *st);
  12626. -time_t make_unix_date3(void *date_ptr);
  12627. -void put_dos_date3(char *buf,int offset,time_t unixdate);
  12628. -void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
  12629. -BOOL in_list(char *s,char *list,BOOL case_sensitive);
  12630. -void strupper(char *s);
  12631. -BOOL file_exist(char *fname,struct stat *sbuf);
  12632. -int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt, long time_out, BOOL exact);
  12633. -void close_sockets(void );
  12634. -BOOL send_smb(int fd,char *buffer);
  12635. -BOOL send_keepalive(int client);
  12636. -int read_data(int fd,char *buffer,int N);
  12637. -int smb_len(char *buf);
  12638. -BOOL receive_smb(int fd,char *buffer,int timeout);
  12639. -void show_msg(char *buf);
  12640. -BOOL big_endian(void );
  12641. -BOOL become_user(int cnum, int uid);
  12642. -BOOL unbecome_user(void);
  12643. -void become_daemon(void);
  12644. -BOOL reduce_name(char *s,char *dir,BOOL widelinks);
  12645. -void strlower(char *s);
  12646. -void strnorm(char *s);
  12647. -char *smb_buf(char *buf);
  12648. -char *smb_trans2_param(char *buf);
  12649. -char *smb_trans2_data(char *buf);
  12650. -BOOL strequal(char *,char *);
  12651. -BOOL strnequal(char *,char *,int n);
  12652. -BOOL strcsequal(char *,char *);
  12653. -BOOL mask_match( char *str, char *regexp, int case_sig, BOOL trans2);
  12654. -int dos_mode(int ,char *,struct stat *);
  12655. -char *timestring();
  12656. -BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
  12657. -BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
  12658. -char *get_home_dir(char *);
  12659. -int set_filelen(int fd, long len);
  12660. -void put_dos_date(char *buf,int offset,time_t unixdate);
  12661. -void put_dos_date2(char *buf,int offset,time_t unixdate);
  12662. -int lp_keepalive(void);
  12663. -int name_len(char *s);
  12664. -void dos_clean_name(char *s);
  12665. -void unix_clean_name(char *s);
  12666. -time_t make_unix_date(void *date_ptr);
  12667. -BOOL lanman2_match( char *str, char *regexp, int case_sig, BOOL autoext);
  12668. -BOOL trim_string(char *s,char *front,char *back);
  12669. -int byte_checksum(char *buf,int len);
  12670. -BOOL yesno(char *p);
  12671. -uint32 file_size(char *file_name);
  12672. -void dos_format(char *fname);
  12673. -char *GetWd(char *s);
  12674. -int name_mangle(char *in,char *out,char name_type);
  12675. -int name_len(char *s);
  12676. -void create_mangled_stack(int size);
  12677. -int name_extract(char *buf,int ofs,char *name);
  12678. -void get_broadcast(struct in_addr *if_ipaddr, struct in_addr *if_bcast, struct in_addr *if_nmask);
  12679. -BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
  12680.  #ifdef __STDC__
  12681.  int Debug1(char *, ...);
  12682.  #else
  12683.  int Debug1();
  12684.  #endif
  12685. -BOOL check_hosts_equiv(char *user);
  12686. -int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
  12687. -void close_cnum(int cnum,int uid);
  12688. -char *smb_errstr(char *inbuf);
  12689. -void GetTimeOfDay(struct timeval *tval);
  12690. -struct tm *LocalTime(time_t *t);
  12691. -int TimeDiff(time_t t);
  12692. -BOOL set_filetime(char *fname,time_t mtime);
  12693. -char *dirname_dos(char *path,char *buf);
  12694. -BOOL get_myname(char *myname,struct in_addr *ip);
  12695. -void expand_mask(char *Mask, BOOL);
  12696. -char *smb_fn_name(int cnum);
  12697. -void get_machine_info(void);
  12698. -int open_socket_in(int type, int port, int dlevel);
  12699. -int open_socket_out(int type,struct in_addr *addr, int port );
  12700. -struct in_addr *interpret_addr2(char *str);
  12701. -BOOL zero_ip(struct in_addr ip);
  12702. -int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
  12703. -int interpret_protocol(char *str,int def);
  12704. -int interpret_security(char *str,int def);
  12705. -int ChDir(char *path);
  12706. -int smb_buflen(char *buf);
  12707. -unsigned long interpret_addr(char *str);
  12708. -void mangle_name_83(char *s);
  12709. -BOOL lp_casesignames(void);
  12710. -void setup_logging(char *pname,BOOL interactive);
  12711. +
  12712.  #ifdef DFS_AUTH
  12713.  void dfs_unlogin(void);
  12714.  extern int dcelogin_atmost_once;
  12715.  #endif
  12716. +
  12717.  #if AJT
  12718.  void ajt_panic(void);
  12719.  #endif
  12720. +
  12721.  #ifdef NOSTRDUP
  12722.  char *strdup(char *s);
  12723.  #endif
  12724. +
  12725.  #ifdef REPLACE_STRLEN
  12726.  int Strlen(char *);
  12727.  #endif
  12728. +
  12729.  #ifdef REPLACE_STRSTR
  12730.  char *Strstr(char *s, char *p);
  12731.  #endif
  12732. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/smbencrypt.c samba-1.9.16alpha5/source/smbencrypt.c
  12733. --- samba-1.9.16alpha4/source/smbencrypt.c    Wed May 29 17:54:25 1996
  12734. +++ samba-1.9.16alpha5/source/smbencrypt.c    Wed Jun  5 01:16:29 1996
  12735. @@ -28,19 +28,6 @@
  12736.  
  12737.  extern int DEBUGLEVEL;
  12738.  
  12739. -#ifndef uchar
  12740. -#define uchar unsigned char
  12741. -#endif
  12742. -#ifndef int16
  12743. -#define int16 unsigned short
  12744. -#endif
  12745. -#ifndef uint16
  12746. -#define uint16 unsigned short
  12747. -#endif
  12748. -#ifndef uint32
  12749. -#define uint32 unsigned int
  12750. -#endif
  12751. -
  12752.  #include "byteorder.h"
  12753.  
  12754.  void str_to_key(uchar *str,uchar *key)
  12755. @@ -198,5 +185,5 @@
  12756.  }
  12757.  
  12758.  #else
  12759. -void smbencrypt_dummy(void){}
  12760. + void smbencrypt_dummy(void){}
  12761.  #endif
  12762. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/smbpass.c samba-1.9.16alpha5/source/smbpass.c
  12763. --- samba-1.9.16alpha4/source/smbpass.c    Wed May 29 17:54:25 1996
  12764. +++ samba-1.9.16alpha5/source/smbpass.c    Wed Jun  5 01:16:29 1996
  12765. @@ -297,8 +297,7 @@
  12766.      return NULL;
  12767.  }
  12768.  #else
  12769. -void 
  12770. -smbpass_dummy(void)
  12771. + void smbpass_dummy(void)
  12772.  {
  12773.  }                /* To avoid compiler complaints */
  12774.  #endif
  12775. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/smbpasswd.c samba-1.9.16alpha5/source/smbpasswd.c
  12776. --- samba-1.9.16alpha4/source/smbpasswd.c    Sat Jun  1 01:15:13 1996
  12777. +++ samba-1.9.16alpha5/source/smbpasswd.c    Wed Jun  5 01:16:29 1996
  12778. @@ -201,14 +201,13 @@
  12779.  /*
  12780.   * Print command usage on stderr and die.
  12781.   */
  12782. -void 
  12783. -usage(char *name)
  12784. +static void usage(char *name)
  12785.  {
  12786.      fprintf(stderr, "Usage is : %s [username]\n", name);
  12787.      exit(1);
  12788.  }
  12789.  
  12790. -int main(int argc, char **argv)
  12791. + int main(int argc, char **argv)
  12792.  {
  12793.    int             real_uid;
  12794.    struct passwd  *pwd;
  12795. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/smbrun.c samba-1.9.16alpha5/source/smbrun.c
  12796. --- samba-1.9.16alpha4/source/smbrun.c    Sat May  4 17:50:25 1996
  12797. +++ samba-1.9.16alpha5/source/smbrun.c    Wed Jun  5 01:16:29 1996
  12798. @@ -44,53 +44,54 @@
  12799.  This is a wrapper around the system call to allow commands to run correctly 
  12800.  as non root from a program which is switching between root and non-root 
  12801.  
  12802. -It takes one argument as argv[1] and runs it after becoming a non-root
  12803. -user
  12804. -*/
  12805. -int main(int argc,char *argv[])
  12806. +It takes 3 arguments as uid,gid,command and runs command after
  12807. +becoming a non-root user */
  12808. + int main(int argc,char *argv[])
  12809.  {
  12810. +  int uid,gid;
  12811. +
  12812.    close_fds();
  12813.  
  12814. -  if (getuid() != geteuid())
  12815. -    {
  12816. -      int uid,gid;
  12817. -      
  12818. -      if (getuid() == 0)
  12819. -    uid = geteuid();
  12820. -      else
  12821. -    uid = getuid();
  12822. -      
  12823. -      if (getgid() == 0)
  12824. -    gid = getegid();
  12825. -      else
  12826. -    gid = getgid();
  12827. -      
  12828. +  if (argc != 4) exit(2);
  12829. +
  12830. +  uid = atoi(argv[1]);
  12831. +  gid = atoi(argv[2]);
  12832. +
  12833. +  /* first become root - we may need to do this in order to lose
  12834. +     our privilages! */
  12835.  #ifdef USE_SETRES
  12836. -      setresgid(0,0,0);
  12837. -      setresuid(0,0,0);
  12838. -      setresgid(gid,gid,gid);
  12839. -      setresuid(uid,uid,uid);      
  12840. +  setresgid(0,0,0);
  12841. +  setresuid(0,0,0);
  12842.  #else      
  12843. -      setuid(0);
  12844. -      seteuid(0);
  12845. -      setgid(gid);
  12846. -      setegid(gid);
  12847. -      setuid(uid);
  12848. -      seteuid(uid);
  12849. +  setuid(0);
  12850. +  seteuid(0);
  12851.  #endif
  12852.  
  12853. -      if (getuid() != uid)
  12854. -    return(3);
  12855. -    }
  12856. +#ifdef USE_SETFS
  12857. +  setfsuid(uid);
  12858. +  setfsgid(gid);
  12859. +#endif
  12860. +
  12861. +#ifdef USE_SETRES
  12862. +  setresgid(gid,gid,gid);
  12863. +  setresuid(uid,uid,uid);      
  12864. +#else
  12865. +  setgid(gid);
  12866. +  setegid(gid);
  12867. +  setuid(uid);
  12868. +  seteuid(uid);
  12869. +#endif
  12870.  
  12871. -  if (geteuid() != getuid())
  12872. -    return(1);
  12873.  
  12874. -  if (argc < 2)
  12875. -    return(2);
  12876. +  /* paranoia :-) */
  12877. +  if (getuid() != uid)
  12878. +    return(3);
  12879. +
  12880. +  if (geteuid() != getuid())
  12881. +    return(4);
  12882.  
  12883.    /* this is to make sure that the system() call doesn't run forever */
  12884.    alarm(30);
  12885.  
  12886. -  return(system(argv[1]));
  12887. +  return(system(argv[3]));
  12888.  }
  12889. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/sockspy.c samba-1.9.16alpha5/source/sockspy.c
  12890. --- samba-1.9.16alpha4/source/sockspy.c    Sat May  4 17:50:25 1996
  12891. +++ samba-1.9.16alpha5/source/sockspy.c    Thu Jan  1 10:00:00 1970
  12892. @@ -1,302 +0,0 @@
  12893. -/*
  12894. - USAGE
  12895. -   sockspy desthost destservice
  12896. -
  12897. -You install this program in /etc/inetd.conf and /etc/services
  12898. -
  12899. -For example I have used these entries:
  12900. -
  12901. -/etc/services:
  12902. -spy        8001/tcp    spy port
  12903. -
  12904. -/etc/inetd.conf:
  12905. -spy stream tcp nowait tridge /usr/local/smb/sockspy sockspy fjall netbios-ssn
  12906. -
  12907. -This means any connection to port 8001 will be redirected to
  12908. -netbios-ssn on fjall. By playing with these parameters you can easily
  12909. -spy on most of the tcp protocols. All packets traversing the link will
  12910. -be captured.
  12911. -
  12912. -NOTE: This program is totally unsupported. I haven't used it for 2
  12913. -years, and don't intend to fix the obvious bugs/limitations. I will,
  12914. -however, accept contributed patches - or even a total rewrite :-)
  12915. -*/
  12916. -
  12917. -#include <stdio.h>
  12918. -#include <strings.h>
  12919. -#include <sys/types.h>
  12920. -#include <sys/dir.h>
  12921. -#include <sys/socket.h>
  12922. -#include <sys/ioctl.h>
  12923. -#include <netinet/in.h>
  12924. -#include <netdb.h>
  12925. -
  12926. -#include <signal.h>
  12927. -
  12928. -#include <errno.h>
  12929. -#include <sysexits.h>
  12930. -
  12931. -int trans_num = 0;
  12932. -
  12933. -#ifndef LOGIN
  12934. -#define LOGIN "/tmp/spy.in"
  12935. -#endif
  12936. -
  12937. -#ifndef LOGOUT
  12938. -#define LOGOUT "/tmp/spy.out"
  12939. -#endif
  12940. -
  12941. -#ifndef LOGCMD
  12942. -#define LOGCMD "/tmp/spy.cmd"
  12943. -#endif
  12944. -
  12945. -FILE *cmd = NULL;
  12946. -FILE *login = NULL;
  12947. -FILE *logout = NULL;
  12948. -
  12949. -#define      STREQL(a, b)        (strcmp(a, b) == 0)
  12950. -#define      NIL                 (0)
  12951. -
  12952. -char      DestHost[256];    /* Remote system to connect to         */
  12953. -char      DestObj[256];     /* Remote object/service to connect to */
  12954. -
  12955. -/* Signal handler for SIGPIPE (write on a disconnected socket) */
  12956. -abort()
  12957. -{
  12958. -  if (cmd)
  12959. -    {
  12960. -      fprintf(cmd,"writing to disconnected socket!\n");
  12961. -      fflush(cmd);
  12962. -    }
  12963. -    exit(1);
  12964. -}
  12965. -
  12966. -
  12967. -main(argc, argv)
  12968. -int    argc;           /* # of command line arguments */
  12969. -char   *argv[];        /* the command line arguments  */
  12970. -{
  12971. -  int      client,       /* Socket connected to client  */
  12972. -  server;       /* Socket to use for server    */
  12973. -
  12974. -  trans_num = 0;
  12975. -#ifndef NOLOG
  12976. -  login = fopen(LOGIN,"w");
  12977. -  logout = fopen(LOGOUT,"w");
  12978. -  cmd = fopen(LOGCMD,"w");
  12979. -#endif
  12980. -
  12981. -  if (cmd)
  12982. -    {
  12983. -      fprintf(cmd,"Started server\n");
  12984. -      fflush(cmd);
  12985. -    }
  12986. -
  12987. -  /* Check usage */
  12988. -  if(argc != 3)
  12989. -    return;
  12990. -
  12991. -  strcpy(DestHost,argv[1]);
  12992. -  strcpy(DestObj,argv[2]);
  12993. -  
  12994. -  /* Time to attempt the connection */
  12995. -  server = inet_conn(DestHost, DestObj);
  12996. -
  12997. -  if( server < 0 ) {
  12998. -    exit(EX_CANTCREAT);
  12999. -  }
  13000. -
  13001. -  /* Just to make the code more readable */
  13002. -  client = 0;
  13003. -  
  13004. -  /* We will abort gracefully when the client or remote system 
  13005. -     goes away */
  13006. -  signal(SIGPIPE, abort);
  13007. -  
  13008. -  /* Now just go and move raw data between client and 
  13009. -     remote system */
  13010. -  dowork(client, server);
  13011. -  /* ... NEVER RETURNS ... */
  13012. -}
  13013. -
  13014. -dowork(client, server)
  13015. -     int    client, server;      
  13016. -{
  13017. -  
  13018. -  /* select(2) masks for client and remote */
  13019. -  int      ClientMask, ServerMask;
  13020. -  
  13021. -  /* Combined ClientMask and ServerMask */
  13022. -  int      ReadMask;
  13023. -
  13024. -  /* Initialize select(2) masks */
  13025. -  ClientMask = 1<<client;
  13026. -  ServerMask = 1<<server;
  13027. -  
  13028. -  ReadMask = ClientMask | ServerMask;
  13029. -  
  13030. -  /* Now move raw data for the rest of our life between 
  13031. -     client and remote */
  13032. -  for( ; ; ) {
  13033. -    /* Local Variables */
  13034. -    int  SelectReadMask;/* select(2) mask modifiable by select(2) */
  13035. -    int  nready;        /* status return from select(2)           */
  13036. -    
  13037. -    do {
  13038. -      /* Intialize select(2) mask everytime
  13039. -     as select(2) always modifies it */
  13040. -      SelectReadMask = ReadMask;
  13041. -      
  13042. -      /* Wait for data to be present to be moved */
  13043. -      errno = 0;
  13044. -      nready = select(32,&SelectReadMask,(int *)0,(int *)0,NIL);
  13045. -    } while( nready < 0  &&  errno == EINTR );
  13046. -
  13047. -    /* select(2) failed, shouldn't happen.  Exit abnormally */
  13048. -    if( nready < 0 )
  13049. -      exit(EX_SOFTWARE);
  13050. -    
  13051. -    /* Favor the client (for no particular reason) 
  13052. -       if s/he is has data */
  13053. -    if( SelectReadMask & ClientMask )      
  13054. -      {
  13055. -    if (cmd)
  13056. -      fprintf(cmd,"client %d\n",nready);
  13057. -    xfer(client, server,login);
  13058. -      }
  13059. -    
  13060. -    /* Then check on the other guy */
  13061. -    if( SelectReadMask & ServerMask )
  13062. -      {
  13063. -    if (cmd)
  13064. -      fprintf(cmd,"server %d\n",nready);
  13065. -    xfer(server, client,logout);
  13066. -      }
  13067. -  }
  13068. -
  13069. -    /* NEVER REACHED */
  13070. -}
  13071. -
  13072. -#define      BUFSIZE        20000 /* Max bytes to move at a time */
  13073. -
  13074. -xfer(from, to,file)
  13075. -     int      from, to;        /* Move data from "from" to "to" */
  13076. -     FILE *file;
  13077. -{
  13078. -  static char buf[BUFSIZE];      /* Buffer data to be moved      */
  13079. -  int      nready;               /* # bytes readable             */
  13080. -  int      got;                  /* # bytes actually being moved */
  13081. -  int ret;
  13082. -  
  13083. -  /* Query the system how many bytes are ready to be read */
  13084. -  ioctl(from, FIONREAD, &nready);
  13085. -  
  13086. -  if (cmd)
  13087. -    fprintf(cmd,"nready = %d\n",nready);
  13088. -  
  13089. -  /* Only try to get the smaller of nready and BUFSIZE */
  13090. -  got = read(from, buf, nready < BUFSIZE ? nready : BUFSIZE);
  13091. -
  13092. -  /* Zero bytes returned indicates end of stream, exit gracefully */
  13093. -  if( got == 0 )
  13094. -    {
  13095. -      if (cmd)
  13096. -    {
  13097. -      fprintf(cmd,"read 0 bytes exiting\n");
  13098. -      fflush(cmd);
  13099. -    }
  13100. -      if (login)
  13101. -    fclose(login);
  13102. -      if (logout)
  13103. -    fclose(logout);
  13104. -      if (cmd)
  13105. -    fclose(cmd);
  13106. -      exit(EX_OK);
  13107. -    }
  13108. -  
  13109. -  
  13110. -  if (file)
  13111. -    {
  13112. -      fprintf(file,"\nTransaction %d\n",trans_num);
  13113. -      fwrite(buf,got,1,file);
  13114. -      fflush(file);
  13115. -    }
  13116. -  trans_num++;
  13117. -  
  13118. -  /* Now send it accross to the other side */
  13119. -  ret = write(to, buf, got);
  13120. -  
  13121. -  if (cmd)
  13122. -    {
  13123. -      fprintf(cmd,"wrote %d\n",ret);
  13124. -      if (ret < 0)
  13125. -    fprintf(cmd,"error = %s\n",strerror(errno));
  13126. -    }
  13127. -}
  13128. -
  13129. -int
  13130. -inet_conn(host, port)
  13131. -    char *host;
  13132. -    char *port;
  13133. -{
  13134. -  /* Local Vars */
  13135. -  int                sock;      /* Socket to use for the connection */
  13136. -  struct hostent     *hostent;  /* Destination host entry           */
  13137. -  struct servent     *servent;  /* Destination service entry        */
  13138. -  struct sockaddr_in addr;      /* Formated destination for connect */
  13139. -  
  13140. -  /* Fetch the requested host and service entries */
  13141. -  hostent = gethostbyname(host);
  13142. -  if (isdigit(*port))
  13143. -    servent = getservbyport(80, "tcp");
  13144. -  else
  13145. -    servent = getservbyname(port, "tcp");
  13146. -
  13147. -  
  13148. -  if (cmd)
  13149. -    {
  13150. -      fprintf(cmd,"inet_conn %s %s\n",host,port);
  13151. -  
  13152. -      if (servent == NULL)
  13153. -    fprintf(cmd,"servent is NIL\n");
  13154. -      if (hostent == NULL)
  13155. -    fprintf(cmd,"hostent is NIL\n");
  13156. -      if (hostent->h_addrtype != AF_INET)
  13157. -    fprintf(cmd,"not inet type\n");
  13158. -      fflush(cmd);
  13159. -    }
  13160. -
  13161. -
  13162. -  /* No host entry, no service entry, or host is not 
  13163. -     Internet, error! */
  13164. -  if( servent == NIL || 
  13165. -     hostent == NIL || 
  13166. -     hostent->h_addrtype != AF_INET )
  13167. -    return -1;
  13168. -  
  13169. -  /* Get a socket from the system to use for the connection */
  13170. -  if( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
  13171. -    return -1;
  13172. -  
  13173. -  /* Make sure we start with a clean address structure ... */
  13174. -  bzero(&addr, sizeof(addr));
  13175. -  
  13176. -  /* ... then fill in the required fields */
  13177. -  addr.sin_family = AF_INET;
  13178. -  addr.sin_port   = servent->s_port;
  13179. -  bcopy(hostent->h_addr, &addr.sin_addr, hostent->h_length);
  13180. -  
  13181. -  /* Now try to connection to the destination */
  13182. -  if( connect(sock, &addr, sizeof(addr)) < 0 ) {
  13183. -    /* No go, release the socket, and then return error! */
  13184. -    close(sock);
  13185. -    return -1;
  13186. -  }
  13187. -  
  13188. -  /* Success.  Return the connected socket descriptor */
  13189. -  if (cmd)
  13190. -    fprintf(cmd,"returning %d\n",sock);
  13191. -  return sock;
  13192. -}
  13193. -
  13194. -
  13195. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/status.c samba-1.9.16alpha5/source/status.c
  13196. --- samba-1.9.16alpha4/source/status.c    Sat Jun  1 01:15:13 1996
  13197. +++ samba-1.9.16alpha5/source/status.c    Wed Jun  5 01:16:29 1996
  13198. @@ -44,7 +44,7 @@
  13199.  void           Ucrit_addPid(int pid);                 /* added by OH */
  13200.  unsigned int   Ucrit_checkPid(int pid);               /* added by OH */
  13201.  
  13202. -int main(int argc, char *argv[])
  13203. + int main(int argc, char *argv[])
  13204.  {
  13205.    FILE *f;
  13206.    pstring fname;
  13207. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/testparm.c samba-1.9.16alpha5/source/testparm.c
  13208. --- samba-1.9.16alpha4/source/testparm.c    Sat Jun  1 01:15:13 1996
  13209. +++ samba-1.9.16alpha5/source/testparm.c    Wed Jun  5 01:16:29 1996
  13210. @@ -41,7 +41,7 @@
  13211.  extern FILE *dbf;
  13212.  extern int DEBUGLEVEL;
  13213.  
  13214. -int main(int argc, char *argv[])
  13215. + int main(int argc, char *argv[])
  13216.  {
  13217.    pstring configfile;
  13218.    int s;
  13219. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/trans2.c samba-1.9.16alpha5/source/trans2.c
  13220. --- samba-1.9.16alpha4/source/trans2.c    Wed May 29 17:54:26 1996
  13221. +++ samba-1.9.16alpha5/source/trans2.c    Wed Jun  5 01:16:29 1996
  13222. @@ -264,7 +264,7 @@
  13223.    int mode=0;
  13224.    uint32 size=0,len;
  13225.    uint32 mdate=0, adate=0, cdate=0;
  13226. -  char *name_ptr;
  13227. +  char *nameptr;
  13228.    BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
  13229.              strequal(Connections[cnum].dirpath,".") ||
  13230.              strequal(Connections[cnum].dirpath,"/"));
  13231. @@ -349,7 +349,7 @@
  13232.  #endif
  13233.  
  13234.    p = pdata;
  13235. -  name_ptr = p;
  13236. +  nameptr = p;
  13237.  
  13238.    name_map_mangle(fname,False,SNUM(cnum));
  13239.  
  13240. @@ -368,7 +368,7 @@
  13241.        SSVAL(p,l1_attrFile,mode);
  13242.        SCVAL(p,l1_cchName,strlen(fname));
  13243.        strcpy(p + l1_achName, fname);
  13244. -      name_ptr = p + l1_achName;
  13245. +      nameptr = p + l1_achName;
  13246.        p += l1_achName + strlen(fname) + 1;
  13247.        break;
  13248.  
  13249. @@ -387,7 +387,7 @@
  13250.        SIVAL(p,l2_cbList,0); /* No extended attributes */
  13251.        SCVAL(p,l2_cchName,strlen(fname));
  13252.        strcpy(p + l2_achName, fname);
  13253. -      name_ptr = p + l2_achName;
  13254. +      nameptr = p + l2_achName;
  13255.        p += l2_achName + strlen(fname) + 1;
  13256.        break;
  13257.  
  13258. @@ -402,7 +402,7 @@
  13259.        SIVAL(p,26,4);
  13260.        CVAL(p,30) = strlen(fname);
  13261.        strcpy(p+31, fname);
  13262. -      name_ptr = p+31;
  13263. +      nameptr = p+31;
  13264.        p += 31 + strlen(fname) + 1;
  13265.        break;
  13266.  
  13267. @@ -420,7 +420,7 @@
  13268.        SSVAL(p,24,mode);
  13269.        CVAL(p,32) = strlen(fname);
  13270.        strcpy(p + 33, fname);
  13271. -      name_ptr = p+33;
  13272. +      nameptr = p+33;
  13273.        p += 33 + strlen(fname) + 1;
  13274.        break;
  13275.  
  13276. @@ -452,7 +452,7 @@
  13277.        strupper(p+2);
  13278.        SSVAL(p,0,strlen(p+2));
  13279.        p += 2 + 24;
  13280. -      /* name_ptr = p;  */
  13281. +      /* nameptr = p;  */
  13282.        strcpy(p,fname); p += strlen(p);
  13283.        p = pdata + len;
  13284.        break;
  13285. @@ -517,7 +517,7 @@
  13286.    }
  13287.  
  13288.    /* Setup the last_filename pointer, as an offset from base_data */
  13289. -  *last_name_off = PTR_DIFF(name_ptr,base_data);
  13290. +  *last_name_off = PTR_DIFF(nameptr,base_data);
  13291.    /* Advance the data pointer to the next slot */
  13292.    *ppdata = p;
  13293.    return(found);
  13294. @@ -1004,7 +1004,7 @@
  13295.  
  13296.  
  13297.    if (tran_call == TRANSACT2_QFILEINFO) {
  13298. -    int16 fnum = SVAL(params,0);
  13299. +    int16 fnum = SVALS(params,0);
  13300.      info_level = SVAL(params,2);
  13301.  
  13302.      CHECK_FNUM(fnum,cnum);
  13303. @@ -1198,7 +1198,7 @@
  13304.      return(ERROR(ERRSRV,ERRaccess));
  13305.  
  13306.    if (tran_call == TRANSACT2_SETFILEINFO) {
  13307. -    int16 fnum = SVAL(params,0);
  13308. +    int16 fnum = SVALS(params,0);
  13309.      info_level = SVAL(params,2);    
  13310.  
  13311.      CHECK_FNUM(fnum,cnum);
  13312. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/ufc.c samba-1.9.16alpha5/source/ufc.c
  13313. --- samba-1.9.16alpha4/source/ufc.c    Sat May  4 17:50:25 1996
  13314. +++ samba-1.9.16alpha5/source/ufc.c    Wed Jun  5 01:16:29 1996
  13315. @@ -777,6 +777,6 @@
  13316.  
  13317.  
  13318.  #else
  13319. -int ufc_dummy_procedure(void)
  13320. + int ufc_dummy_procedure(void)
  13321.  {return 0;}
  13322.  #endif
  13323. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/uid.c samba-1.9.16alpha5/source/uid.c
  13324. --- samba-1.9.16alpha4/source/uid.c    Thu Jan  1 10:00:00 1970
  13325. +++ samba-1.9.16alpha5/source/uid.c    Wed Jun  5 01:16:29 1996
  13326. @@ -0,0 +1,360 @@
  13327. +/* 
  13328. +   Unix SMB/Netbios implementation.
  13329. +   Version 1.9.
  13330. +   uid/user handling
  13331. +   Copyright (C) Andrew Tridgell 1992-1995
  13332. +   
  13333. +   This program is free software; you can redistribute it and/or modify
  13334. +   it under the terms of the GNU General Public License as published by
  13335. +   the Free Software Foundation; either version 2 of the License, or
  13336. +   (at your option) any later version.
  13337. +   
  13338. +   This program is distributed in the hope that it will be useful,
  13339. +   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13340. +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13341. +   GNU General Public License for more details.
  13342. +   
  13343. +   You should have received a copy of the GNU General Public License
  13344. +   along with this program; if not, write to the Free Software
  13345. +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13346. +*/
  13347. +
  13348. +#include "includes.h"
  13349. +#include "loadparm.h"
  13350. +
  13351. +extern int DEBUGLEVEL;
  13352. +
  13353. +extern connection_struct Connections[];
  13354. +
  13355. +static int initial_uid;
  13356. +static int initial_gid;
  13357. +static int old_umask = 022;
  13358. +
  13359. +static pstring OriginalDir;
  13360. +
  13361. +/* what user is current? */
  13362. +struct current_user current_user;
  13363. +
  13364. +/****************************************************************************
  13365. +initialise the uid routines
  13366. +****************************************************************************/
  13367. +void init_uid(void)
  13368. +{
  13369. +  initial_uid = current_user.uid = geteuid();
  13370. +  initial_gid = current_user.gid = getegid();
  13371. +
  13372. +  if (initial_gid != 0 && initial_uid == 0)
  13373. +    {
  13374. +#ifdef HPUX
  13375. +      setresgid(0,0,0);
  13376. +#else
  13377. +      setgid(0);
  13378. +      setegid(0);
  13379. +#endif
  13380. +    }
  13381. +
  13382. +  initial_uid = geteuid();
  13383. +  initial_gid = getegid();
  13384. +
  13385. +  current_user.cnum = -1;
  13386. +
  13387. +  GetWd(OriginalDir);
  13388. +}
  13389. +
  13390. +
  13391. +/****************************************************************************
  13392. +  become the specified uid 
  13393. +****************************************************************************/
  13394. +static BOOL become_uid(int uid)
  13395. +{
  13396. +  if (initial_uid != 0)
  13397. +    return(True);
  13398. +
  13399. +#ifdef AIX
  13400. +  {
  13401. +    /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */
  13402. +    priv_t priv;
  13403. +
  13404. +    priv.pv_priv[0] = 0;
  13405. +    priv.pv_priv[1] = 0;
  13406. +    if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH,
  13407. +        &priv, sizeof(priv_t)) < 0 ||
  13408. +    setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 ||
  13409. +    seteuid((uid_t)uid) < 0) 
  13410. +      DEBUG(1,("Can't set uid (AIX3)"));
  13411. +  }
  13412. +#endif
  13413. +
  13414. +#ifdef USE_SETRES
  13415. +  if (setresuid(-1,uid,-1) != 0)
  13416. +#elif defined(USE_SETFS)
  13417. +    if (setfsuid(uid) != 0)
  13418. +#else
  13419. +    if ((seteuid(uid) != 0) && 
  13420. +    (setuid(uid) != 0))
  13421. +#endif
  13422. +      {
  13423. +    DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
  13424. +         uid,getuid(), geteuid()));
  13425. +    if (uid > 32000)
  13426. +      DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
  13427. +    return(False);
  13428. +      }
  13429. +
  13430. +  if (((uid == -1) || (uid == 65535)) && geteuid() != uid) {
  13431. +    DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
  13432. +    return(False);
  13433. +  }
  13434. +
  13435. +  current_user.uid = uid;
  13436. +
  13437. +  return(True);
  13438. +}
  13439. +
  13440. +
  13441. +/****************************************************************************
  13442. +  become the specified gid
  13443. +****************************************************************************/
  13444. +static BOOL become_gid(int gid)
  13445. +{
  13446. +  if (initial_uid != 0)
  13447. +    return(True);
  13448. +  
  13449. +#ifdef USE_SETRES 
  13450. +  if (setresgid(-1,gid,-1) != 0)
  13451. +#elif defined(USE_SETFS)
  13452. +  if (setfsgid(gid) != 0)
  13453. +#else
  13454. +  if (setgid(gid) != 0)
  13455. +#endif
  13456. +      {
  13457. +    DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
  13458. +         gid,getgid(),getegid()));
  13459. +    if (gid > 32000)
  13460. +      DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
  13461. +    return(False);
  13462. +      }
  13463. +
  13464. +  current_user.gid = gid;
  13465. +
  13466. +  return(True);
  13467. +}
  13468. +
  13469. +
  13470. +/****************************************************************************
  13471. +  become the specified uid and gid
  13472. +****************************************************************************/
  13473. +static BOOL become_id(int uid,int gid)
  13474. +{
  13475. +  return(become_gid(gid) && become_uid(uid));
  13476. +}
  13477. +
  13478. +/****************************************************************************
  13479. +become the guest user
  13480. +****************************************************************************/
  13481. +BOOL become_guest(void)
  13482. +{
  13483. +  BOOL ret;
  13484. +  static struct passwd *pass=NULL;
  13485. +
  13486. +  if (initial_uid != 0) 
  13487. +    return(True);
  13488. +
  13489. +  if (!pass)
  13490. +    pass = Get_Pwnam(lp_guestaccount(-1),True);
  13491. +  if (!pass) return(False);
  13492. +
  13493. +  ret = become_id(pass->pw_uid,pass->pw_gid);
  13494. +
  13495. +  if (!ret)
  13496. +    DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
  13497. +
  13498. +  current_user.cnum = -2;
  13499. +
  13500. +  return(ret);
  13501. +}
  13502. +
  13503. +/*******************************************************************
  13504. +check if a username is OK
  13505. +********************************************************************/
  13506. +static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
  13507. +{
  13508. +  int i;
  13509. +  for (i=0;i<Connections[cnum].uid_cache.entries;i++)
  13510. +    if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True);
  13511. +
  13512. +  if (!user_ok(vuser->name,snum)) return(False);
  13513. +
  13514. +  i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE;
  13515. +  Connections[cnum].uid_cache.list[i] = vuser->uid;
  13516. +
  13517. +  if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE)
  13518. +    Connections[cnum].uid_cache.entries++;
  13519. +
  13520. +  return(True);
  13521. +}
  13522. +
  13523. +
  13524. +/****************************************************************************
  13525. +  become the user of a connection number
  13526. +****************************************************************************/
  13527. +BOOL become_user(int cnum, int uid)
  13528. +{
  13529. +  int new_umask;
  13530. +  user_struct *vuser;
  13531. +  int snum,gid;
  13532. +  int id = uid;
  13533. +
  13534. +  if (current_user.cnum == cnum && current_user.id == id) {
  13535. +    DEBUG(4,("Skipping become_user - already user\n"));
  13536. +    return(True);
  13537. +  }
  13538. +
  13539. +  unbecome_user();
  13540. +
  13541. +  if (!OPEN_CNUM(cnum)) {
  13542. +    DEBUG(2,("Connection %d not open\n",cnum));
  13543. +    return(False);
  13544. +  }
  13545. +
  13546. +  snum = Connections[cnum].service;
  13547. +
  13548. +  if (Connections[cnum].force_user || 
  13549. +      lp_security() == SEC_SHARE ||
  13550. +      !(vuser = get_valid_user_struct(uid)) ||
  13551. +      !check_user_ok(cnum,vuser,snum)) {
  13552. +    uid = Connections[cnum].uid;
  13553. +    gid = Connections[cnum].gid;
  13554. +    current_user.groups = Connections[cnum].groups;
  13555. +    current_user.igroups = Connections[cnum].igroups;
  13556. +    current_user.ngroups = Connections[cnum].ngroups;
  13557. +  } else {
  13558. +    if (!vuser) {
  13559. +      DEBUG(2,("Invalid vuid used %d\n",uid));
  13560. +      return(False);
  13561. +    }
  13562. +    uid = vuser->uid;
  13563. +    if(!*lp_force_group(snum))
  13564. +      gid = vuser->gid;
  13565. +    else
  13566. +      gid = Connections[cnum].gid;
  13567. +    current_user.groups = vuser->user_groups;
  13568. +    current_user.igroups = vuser->user_igroups;
  13569. +    current_user.ngroups = vuser->user_ngroups;
  13570. +  }
  13571. +
  13572. +  if (initial_uid == 0)
  13573. +    {
  13574. +      if (!become_gid(gid)) return(False);
  13575. +
  13576. +#ifndef NO_SETGROUPS      
  13577. +      if (!IS_IPC(cnum)) {
  13578. +    /* groups stuff added by ih/wreu */
  13579. +    if (current_user.ngroups > 0)
  13580. +      if (setgroups(current_user.ngroups,current_user.groups)<0)
  13581. +        DEBUG(0,("setgroups call failed!\n"));
  13582. +      }
  13583. +#endif
  13584. +
  13585. +      if (!Connections[cnum].admin_user && !become_uid(uid))
  13586. +    return(False);
  13587. +    }
  13588. +
  13589. +  new_umask = 0777 & ~CREATE_MODE(cnum);
  13590. +  old_umask = umask(new_umask);
  13591. +
  13592. +  current_user.cnum = cnum;
  13593. +  current_user.id = id;
  13594. +  
  13595. +  DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d) new_umask=0%o\n",
  13596. +       getuid(),geteuid(),getgid(),getegid(),new_umask));
  13597. +  
  13598. +  return(True);
  13599. +}
  13600. +
  13601. +/****************************************************************************
  13602. +  unbecome the user of a connection number
  13603. +****************************************************************************/
  13604. +BOOL unbecome_user(void )
  13605. +{
  13606. +  if (current_user.cnum == -1)
  13607. +    return(False);
  13608. +
  13609. +  ChDir(OriginalDir);
  13610. +
  13611. +  umask(old_umask);
  13612. +
  13613. +  if (initial_uid == 0)
  13614. +    {
  13615. +#ifdef USE_SETRES
  13616. +      setresuid(-1,getuid(),-1);
  13617. +      setresgid(-1,getgid(),-1);
  13618. +#elif defined(USE_SETFS)
  13619. +      setfsuid(initial_uid);
  13620. +      setfsgid(initial_gid);
  13621. +#else
  13622. +      if (seteuid(initial_uid) != 0) 
  13623. +    setuid(initial_uid);
  13624. +      setgid(initial_gid);
  13625. +#endif
  13626. +    }
  13627. +#ifdef NO_EID
  13628. +  if (initial_uid == 0)
  13629. +    DEBUG(2,("Running with no EID\n"));
  13630. +  initial_uid = getuid();
  13631. +  initial_gid = getgid();
  13632. +#else
  13633. +  if (geteuid() != initial_uid)
  13634. +    {
  13635. +      DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
  13636. +      initial_uid = geteuid();
  13637. +    }
  13638. +  if (getegid() != initial_gid)
  13639. +    {
  13640. +      DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
  13641. +      initial_gid = getegid();
  13642. +    }
  13643. +#endif
  13644. +
  13645. +  current_user.uid = initial_uid;
  13646. +  current_user.gid = initial_gid;
  13647. +  
  13648. +  if (ChDir(OriginalDir) != 0)
  13649. +    DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
  13650. +         timestring(),OriginalDir));  
  13651. +
  13652. +  DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
  13653. +    getuid(),geteuid(),getgid(),getegid()));
  13654. +
  13655. +  current_user.cnum = -1;
  13656. +
  13657. +  return(True);
  13658. +}
  13659. +
  13660. +
  13661. +/****************************************************************************
  13662. +run a command via system() using smbrun, being careful about uid/gid handling
  13663. +****************************************************************************/
  13664. +int smbrun(char *cmd,char *outfile)
  13665. +{
  13666. +  int ret;
  13667. +  pstring syscmd;  
  13668. +  char *path = lp_smbrun();
  13669. +
  13670. +  if (!file_exist(path,NULL))
  13671. +    {
  13672. +      DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path));
  13673. +      return(1);
  13674. +    }
  13675. +
  13676. +  sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"",
  13677. +      path,current_user.uid,current_user.gid,cmd,
  13678. +      outfile?outfile:"/dev/null");
  13679. +
  13680. +  DEBUG(5,("smbrun - running %s ",syscmd));
  13681. +  ret = system(syscmd);
  13682. +  DEBUG(5,("gave %d\n",ret));
  13683. +  return(ret);
  13684. +}
  13685. +
  13686. +
  13687. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/util.c samba-1.9.16alpha5/source/util.c
  13688. --- samba-1.9.16alpha4/source/util.c    Sat Jun  1 01:15:13 1996
  13689. +++ samba-1.9.16alpha5/source/util.c    Wed Jun  5 01:16:30 1996
  13690. @@ -182,10 +182,10 @@
  13691.  macro
  13692.  ********************************************************************/
  13693.  #ifdef __STDC__
  13694. -int Debug1(char *format_str, ...)
  13695. + int Debug1(char *format_str, ...)
  13696.  {
  13697.  #else
  13698. -int Debug1(va_alist)
  13699. + int Debug1(va_alist)
  13700.  va_dcl
  13701.  {  
  13702.    char *format_str;
  13703. @@ -1820,11 +1820,10 @@
  13704.    bzero((char *)&sock,socklen);
  13705.    bzero((char *)&lastip,sizeof(lastip));
  13706.    ret = recvfrom(fd,buf,len,0,&sock,&socklen);
  13707. -  if (ret <= 0)
  13708. -    {
  13709. -      DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
  13710. -      return(0);
  13711. -    }
  13712. +  if (ret <= 0) {
  13713. +    DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
  13714. +    return(0);
  13715. +  }
  13716.  
  13717.    lastip = *(struct in_addr *) &sock.sa_data[2];
  13718.    lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
  13719. @@ -3234,7 +3233,7 @@
  13720.  /****************************************************************************
  13721.  duplicate a string
  13722.  ****************************************************************************/
  13723. -char *strdup(char *s)
  13724. + char *strdup(char *s)
  13725.  {
  13726.    char *ret = NULL;
  13727.    if (!s) return(NULL);
  13728. @@ -3260,7 +3259,7 @@
  13729.  /****************************************************************************
  13730.  a replacement strlen() that returns int for solaris
  13731.  ****************************************************************************/
  13732. -int Strlen(char *s)
  13733. + int Strlen(char *s)
  13734.  {
  13735.    int ret=0;
  13736.    if (!s) return(0);
  13737. @@ -3274,7 +3273,7 @@
  13738.   /*******************************************************************
  13739.  ftruncate for operating systems that don't have it
  13740.  ********************************************************************/
  13741. -int ftruncate(int f,long l)
  13742. + int ftruncate(int f,long l)
  13743.  {
  13744.        struct  flock   fl;
  13745.  
  13746. @@ -3382,7 +3381,7 @@
  13747.    if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
  13748.      { 
  13749.        if (port) {
  13750. -    if (port == 139 || port == 137)
  13751. +    if (port == SMB_PORT || port == NMB_PORT)
  13752.        DEBUG(dlevel,("bind failed on port %d (%s)\n",
  13753.              port,strerror(errno))); 
  13754.      close(res); 
  13755. @@ -3570,6 +3569,21 @@
  13756.  
  13757.  
  13758.  /*******************************************************************
  13759. +are two IPs on the same subnet?
  13760. +********************************************************************/
  13761. +BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
  13762. +{
  13763. +  unsigned long net1,net2,nmask;
  13764. +
  13765. +  nmask = ntohl(mask.s_addr);
  13766. +  net1  = ntohl(ip1.s_addr);
  13767. +  net2  = ntohl(ip2.s_addr);
  13768. +            
  13769. +  return((net1 & nmask) == (net2 & nmask));
  13770. +}
  13771. +
  13772. +
  13773. +/*******************************************************************
  13774.  write a string in unicoode format
  13775.  ********************************************************************/
  13776.  int PutUniCode(char *dst,char *src)
  13777. @@ -3585,34 +3599,6 @@
  13778.    return(ret);
  13779.  }
  13780.  
  13781. -
  13782. -pstring smbrun_path = SMBRUN;
  13783. -
  13784. -/****************************************************************************
  13785. -run a command via system() using smbrun
  13786. -****************************************************************************/
  13787. -int smbrun(char *cmd,char *outfile)
  13788. -{
  13789. -  int ret;
  13790. -  pstring syscmd;  
  13791. -
  13792. -  if (!file_exist(smbrun_path,NULL))
  13793. -    {
  13794. -      DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",smbrun_path));
  13795. -      return(1);
  13796. -    }
  13797. -
  13798. -  sprintf(syscmd,"%s \"(%s 2>&1) > %s\"",
  13799. -      smbrun_path,cmd,
  13800. -      outfile?outfile:"/dev/null");
  13801. -
  13802. -  DEBUG(5,("smbrun - running %s ",syscmd));
  13803. -  ret = system(syscmd);
  13804. -  DEBUG(5,("gave %d\n",ret));
  13805. -  return(ret);
  13806. -}
  13807. -
  13808. -
  13809.  /****************************************************************************
  13810.  a wrapper for gethostbyname() that tries with all lower and all upper case 
  13811.  if the initial name fails
  13812. @@ -3745,8 +3731,7 @@
  13813.  ********************************************************************/
  13814.  void ajt_panic(void)
  13815.  {
  13816. -  pstring cmd = "/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &";
  13817. -  smbrun(cmd,NULL);
  13818. +  system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &");
  13819.  }
  13820.  #endif
  13821.  
  13822. @@ -3826,7 +3811,7 @@
  13823.  /****************************************************************************
  13824.   some systems don't have an initgroups call 
  13825.  ****************************************************************************/
  13826. -int initgroups(char *name,gid_t id)
  13827. + int initgroups(char *name,gid_t id)
  13828.  {
  13829.  #ifdef NO_SETGROUPS
  13830.    /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
  13831. @@ -4010,8 +3995,7 @@
  13832.  
  13833.  #ifdef REPLACE_RENAME
  13834.  /* Rename a file. (from libiberty in GNU binutils)  */
  13835. -int
  13836. -rename (zfrom, zto)
  13837. + int rename (zfrom, zto)
  13838.       const char *zfrom;
  13839.       const char *zto;
  13840.  {
  13841. @@ -4032,8 +4016,7 @@
  13842.  /*
  13843.   * Search for a match in a netgroup. This replaces it on broken systems.
  13844.   */
  13845. -int InNetGr(group, host, user, dom)
  13846. -        char *group, *host, *user, *dom;
  13847. +int InNetGr(char *group,char *host,char *user,char *dom)
  13848.  {
  13849.    char *hst, *usr, *dm;
  13850.    
  13851. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/version.h samba-1.9.16alpha5/source/version.h
  13852. --- samba-1.9.16alpha4/source/version.h    Sat Jun  1 01:15:58 1996
  13853. +++ samba-1.9.16alpha5/source/version.h    Wed Jun  5 01:19:46 1996
  13854. @@ -1 +1 @@
  13855. -#define VERSION "1.9.16alpha4"
  13856. +#define VERSION "1.9.16alpha5"
  13857. diff -u -r --new-file --exclude=CVS samba-1.9.16alpha4/source/vt_mode.c samba-1.9.16alpha5/source/vt_mode.c
  13858. --- samba-1.9.16alpha4/source/vt_mode.c    Sat May  4 17:50:25 1996
  13859. +++ samba-1.9.16alpha5/source/vt_mode.c    Wed Jun  5 01:16:30 1996
  13860. @@ -60,8 +60,7 @@
  13861.  /*
  13862.  VT_Check: test incoming packet for "vtp" or "iVT1\0"
  13863.  */
  13864. -int    VT_Check(buffer)
  13865. -char    *buffer;
  13866. +int    VT_Check(char    *buffer)
  13867.  {
  13868.      DEBUG(3,("Checking packet: <%10s...>\n", buffer+4));
  13869.      if((strncmp(buffer+4, "vtp", 3) == 0 && smb_len(buffer) == 3) || (strncmp(buffer+4, "iVT1\0", 5) == 0 && smb_len(buffer) == 5))
  13870. @@ -74,7 +73,7 @@
  13871.  /*
  13872.  VT_Start_utmp: prepare /etc/utmp for /bin/login
  13873.  */
  13874. -VT_Start_utmp()
  13875. +int VT_Start_utmp(void)
  13876.  {
  13877.      struct utmp    u, *v;
  13878.      char        *tt;
  13879. @@ -111,7 +110,7 @@
  13880.  /*
  13881.  VT_Stop_utmp: prepare /etc/utmp for other processes
  13882.  */
  13883. -VT_Stop_utmp()
  13884. +int VT_Stop_utmp(void)
  13885.  {
  13886.      struct utmp    u, *v;
  13887.  
  13888. @@ -138,7 +137,7 @@
  13889.  /*
  13890.  VT_AtExit: Things to do when the program exits
  13891.  */
  13892. -void    VT_AtExit()
  13893. +void    VT_AtExit(void)
  13894.  {
  13895.      if(VT_ChildPID > 0) {
  13896.          kill(VT_ChildPID, SIGHUP);
  13897. @@ -152,8 +151,7 @@
  13898.  /*
  13899.  VT_SigCLD: signalhandler for SIGCLD: set flag if child-process died
  13900.  */
  13901. -void    VT_SigCLD(sig)
  13902. -int    sig;
  13903. +void    VT_SigCLD(int    sig)
  13904.  {
  13905.      if(wait(NULL) == VT_ChildPID)
  13906.          VT_ChildDied = True;
  13907. @@ -165,8 +163,7 @@
  13908.  /*
  13909.  VT_SigEXIT: signalhandler for signals that cause the process to exit
  13910.  */
  13911. -void    VT_SigEXIT(sig)
  13912. -int    sig;
  13913. +void    VT_SigEXIT(int    sig)
  13914.  {
  13915.      VT_AtExit();
  13916.  
  13917. @@ -177,7 +174,7 @@
  13918.  /*
  13919.  VT_Start: initialize vt-specific data, alloc pty, spawn shell and send ACK
  13920.  */
  13921. -int    VT_Start()
  13922. +int    VT_Start(void)
  13923.  {
  13924.      char    OutBuf [64], *X, *Y;
  13925.  
  13926. @@ -330,8 +327,7 @@
  13927.  /*
  13928.  VT_Output: transport data from socket to pty
  13929.  */
  13930. -int    VT_Output(Buffer)
  13931. -char    *Buffer;
  13932. +int    VT_Output(char    *Buffer)
  13933.  {
  13934.      int        i, len, nb;
  13935.  
  13936. @@ -350,9 +346,7 @@
  13937.  /*
  13938.  VT_Input: transport data from pty to socket
  13939.  */
  13940. -int    VT_Input(Buffer, Size)
  13941. -char    *Buffer;
  13942. -int        Size;
  13943. +int    VT_Input(char    *Buffer,int        Size)
  13944.  {
  13945.      int        len;
  13946.  
  13947. @@ -372,7 +366,7 @@
  13948.  /*
  13949.  VT_Process: main loop while in vt-mode
  13950.  */
  13951. -void VT_Process()
  13952. +void VT_Process(void)
  13953.  {
  13954.      static int    trans_num = 0;
  13955.      extern int    Client;
  13956.